How to provide access (Spring Security) [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
How can you put the right, so that only the admin can go to the JSP pages using his username and password. Suppose a page (allStudents.jsp) is available only to the admin, for this he must enter his username and password
How can you put the right, so that only the admin can go to the JSP pages using his username and password. Suppose a page (allStudents.jsp) is available only to the admin, for this he must enter his username and password
package adil.java.schoolmaven.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;
#Order(1)
#Configuration
#EnableWebSecurity
#Component
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("1234"))
.authorities("ROLE_ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/securityNone").permitAll() //??????
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
enter image description here
I am Changed code please view this code
#Order(1)
#Configuration
#EnableWebSecurity
#Component
public class СostumWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("1234"))
.authorities("ROLE_ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/allStudents").hasRole("ADMIN");
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

Full Page Authorization Example
With expressions enabled for the http element, an URL pattern can be
secured as follows:
#Configuration
#EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/allStudents").hasRole("ROLE_ADMIN"); // assuming this is your endpoint/controller for allStudents.jsp page
}
}
Method Level Authorization Example – #PreAuthorize
Security Expressions can be used to secure business functionality at
the method level as well, by using annotations.
The annotations #PreAuthorize and #PostAuthorize (as well as
#PreFilter and #PostFilter) support Spring Expression Language (SpEL)
and provide expression-based access control.
First, in order to use method level security, we need to enable this
in the security configuration using #EnableGlobalMethodSecurity:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
}
Then, we can secure methods using the Spring #PreAuthorize annotation:
#Service
public class FooService {
#PreAuthorize("hasRole('ROLE_ADMIN')")
public List<Foo> findAll() { ... }
...
}
For more in depth explanation for this examples, you can refer to this link

Related

Disable securitycontext without using depricated WebSecurityConfigurerAdapter

I'm trying to rewrite following class in order to get rid of the depricated WebSecurityConfigurerAdapter:
#EnableWebSecurity
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity security) throws Exception {
security.mvcMatcher("/my/path/*").securityContext().disable();
}
}
And I've tried to rewrite this with the help of the official Spring documentation. The following two attempts resulted in 403 Errors when trying to access resources on that path:
#EnableWebSecurity
public class MyWebSecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity security) throws Exception {
security.mvcMatcher("/my/path/*").securityContext().disable();
return security.build();
}
}
#EnableWebSecurity
public class ConsentWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public WebSecurityCustomizer webSecurityCustomizer() throws Exception {
return (web) -> web.ignoring().mvcMatchers("/v1/containers/*");
}
}
While in the original code everything is running
I also faced the same scenario of discarding the deprecated method and replacing it with SecurityFilterChain
if you want to disable the security on given path then try this:
security.mvcMatcher("/my/path/*").permitAll();
Edit: Here is my migrated code which worked fine with permitting every request without authentication.
#Configuration
#EnableWebMvc
public class SecurityConfig {
#Autowired
private UserDetailsService userDetailsService;
#Bean
protected SecurityFilterChain authorizationConfig(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/post/**", "/newcomment/**", "/page/**","/api/","/api/posts/filter",
"/api/comments").permitAll();
return httpSecurity.build();
}
You can use below code for reference
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration {
private final String[] WHITE_LABEL_URLS = {"/blogapp", "/usercreation", "/css/**", "/saveuser", "/page/**"};
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.httpBasic()
.and()
.authorizeHttpRequests()
.antMatchers(WHITE_LABEL_URLS).permitAll()
.anyRequest().authenticated()
.securityContext().disable();
return httpSecurity.build();
}
}

Spring Boot Security - allow without authentication

Spring boot security allow anonymous user
I am trying configure Spring Boot Security to allow anonymous user reach all URLs except one. By default user and generated security password by Spring.
I need just one page for maintanance application
I already tried a lot tips and tutorials.
1
2
3
4
And others.
But Spring still required authetification for all pages.
My current security config
#EnableWebSecurity
#Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.anonymous()
.antMatchers("/secure")
.authenticated();
}
}
Web configuration
#Configuration
#EnableWebMvc
#EnableAsync
public class WebConf implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
WebMvcConfigurer.super.addResourceHandlers(registry);
registry.addResourceHandler("/webjars/**").addResourceLocations("/webjars/**");
}
#Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Asynchronous Process-");
executor.initialize();
return executor;
}
}
And main method
#ComponentScan
#SpringBootApplication
#EnableScheduling
public class MainServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MainServiceApplication.class, args);
}
}
I tried
.permitAll()
.anonymous()
without success.
Edit 1
Project structure
Project structure
Edit 2
Project structure
#ComponentScan()
#SpringBootApplication
#EnableScheduling
public class MainServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MainServiceApplication.class, args);
}
}
Login page
Solved by move config package. Spring did not scan configuration package.
You may need to change the order. Possible issue is antMatchers("/secure").authenticated() has no effect due to /secure endpoint will be considerd in the anyRequest(). Also make sure SecurityConf is in correct package as required for scanning.
#EnableWebSecurity
#Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/secure").authenticated()
.anyRequest().anonymous();
}
}
OR
#EnableWebSecurity
#Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/secure").authenticated()
.anyRequest().permitAll();
}
}
UPDATE
You need to create a configs package inside cz.lh.main_service and SecurityConf and WebConf should be part of the cz.lh.main_service.configs
OR
You can use #ComponentScan and can specify the current package in which you have SecurityConf and WebConf
#ComponentScan(“your-config-package”)

Java - Spring - Basic authentication - How to hash the password defined in application.properties

Iam implementing a basic authentication for Spring Boot application and iam defining my credentials in application.properties class but I want to hash-encode the password and then check if the hash is the same as the hash for the password in application.properties then I can login. If possible to do all of the logic in the configure method then it would be great.
application.properties:
BASIC AUTHENTICATION
user.name=test
user.password={noop}example
SecurityConfig class:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
private AuthenticationProvider authenticationProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic()
.and().sessionManagement().and().authenticationProvider(authenticationProvider)
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
UPDATED CODE
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
#Value("${security.user.password}")
private String password;
#Value("${security.user.name}")
private String username;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated()
.and().logout().and().httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
passwordEncoder(passwordEncoder()).withUser(username).password(password);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public String generateHashedPassword(String password) {
return BCrypt.hashpw(password, BCrypt.gensalt(10));
}
}
UPDATE 2
Currently the way it works now is when i start the application, i visit localhost:8080 then a login popup appears and i type the username and password (that are defined in application.properties)
if I type the right username and password i get logged in but if i manage to login with the username and password defined in application.properties then whats the point with hashing the password? I was thinking more like having a list of hashed keys and compare the input password with the list and if success then login.
Since you want to define your credentials in properties file, I guess you can take advantage of inmemory authentication. Try the following:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
private AuthenticationProvider authenticationProvider;
#Value("${user.name}")
private String userName;
#Value("${user.password}")
private String userHashedPassword; // hashed password
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic()
.and().sessionManagement().and().authenticationProvider(authenticationProvider)
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser(userName)
.password(userHashedPassword);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Please, note, that in this case your password should be encrypted with BCryptPasswordEncoder first, and then you should put it into properties file (you can use its encoder.encode("password") method). Or you can use any other implementation of PasswordEncoder if you want. I've also noticed that you're using some custom autenticationProvider. Not sure how it works since you didnt share the code, and not sure that it will get along with inmemory autentication. But, anyway, I think it worth a shot and this is the right way to go in your scenario.
Hope it helps.
I think you need to implement your own AuthenticationProvider like in this question. In the authenticate() method you can do the hashing of the retrieved password and check if it matches the one from your application.properties.

How to skip authentication for TestRestTemplate in Spring Boot Tests?

Below is my test class. The hello-world endpoint simply returns an HTML page containing text i.e. Hello Stranger!
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloWorldTest {
#Autowired
private HelloWorldController controller;
#Autowired
private TestRestTemplate restTemplate;
#LocalServerPort
private int port;
#Test
public void contextLoads() throws Exception {
assertThat(controller).isNotNull();
}
#Test
public void greetingShouldReturnDefaultMessage() throws Exception {
String baseUrl = "http://localhost:" + port;
assertThat(this.restTemplate.getForObject(baseUrl+"/hello-world", String.class))
.contains("Hello Stranger!");
}
}
This is my Security Config:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
It simply redirects all authenticated users to the login page
I have tried adding #WithMockUser annotation or adding another security config class in my test directory to override the default config. But so far nothing has seemed to work.
Any help or suggestions on documentation to read is appreciated!
Another way to do it that worked for me was to override the normal security configation for running the integration test like so:
#TestConfiguration
#Order(-101)
#EnableWebSecurity
class TestSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity security) throws Exception {
security.httpBasic().and().formLogin().disable();
}
}
I have managed to solve this issue by first creating another web security config without requiring login/authorization, then by adding #Profile to my config class and production/dev/test profile via application.properties in my test directory (i.e. adding "spring.profiles.active=test").
Not sure if this is the best way to solve this issue, but it works for now.

Spring REST security - Secure different URLs differently

I have working REST API under Spring 4 using Basic authentication. These REST services are under /api/v1/** URL. However, I want to add another set of REST endpoints under different url /api/v2/**, but protected with token-based authentication.
Is it possible to do this with one servlet ? How to configure Spring Security to use different forms of authentication for different URLs ?
Thank you.
Here's a code sample in Java config that uses UserDetailsService and has different security configurations for different URL endpoints:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Configuration
#Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/v1/**")
.httpBasic()
.realmName("API")
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/v1/**").authenticated();
}
}
#Configuration
#Order(2)
public static class ApiTokenSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/v2/**")
/* other config options go here... */
}
}
}

Categories