I'm writing an SpringBoot app. When I do requests with Postman - I get this error VERY OFTEN:
java.lang.NullPointerException: null
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.authenticationIsRequired(BasicAuthenticationFilter.java:222) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:166) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Here is my SecurityConfig:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Autowired
private PasswordEncoder passwordEncoder;
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder(8);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/registration", "/restaurants").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.rememberMe()
.and()
.logout()
.permitAll();
//Set enable when frontend added
http.csrf().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(passwordEncoder);
}
}
How to fix it? I need to do request from Postman, so I can't change the login form.
Go to the Authorization tab in your Postman window ( it's under the request type ) and select 'Basic Auth' and fill in your credentials if you're doing any request other than "/", "/registration", "/restaurants".
Related
Hi I have implemeted spring security in springboot . now i want login expiry time of 10 min so that after expiry the page will be redirected to a page
`
#Configuration
#EnableWebSecurity
public class ApplicationSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private LoginSuccessHandler loginSuccessHandler;
#Bean
AuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return authenticationProvider;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/js/**","/webjars/**","/images/**","/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").successHandler(loginSuccessHandler).permitAll()
.and()
.logout().invalidateHttpSession(true).permitAll();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.maximumSessions(1).expiredUrl("/sessionExpired");
/*http.authorizeRequests()
.antMatchers("/")
.permitAll()*/
/*.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.loginProcessingUrl("/checkLogin")
.failureUrl("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.permitAll()*/
/*.and()
.csrf()
.disable()
;*/
}
}
`
For Springboot application you need to set property in application.property named server.servlet.session.timeout=15m. If time unit is not specified by default it takes seconds
I am trying to logout a user in my springboot application but it still log me again
I have referred to this but didn't worked for me Spring Security logout does not work - does not clear security context and authenticated user still exists
This is my SecurityMiddleware code
#EnableWebSecurity
public class SecurityMiddleware implements WebSecurityConfigurer {
#Autowired
private UserRepository userRepository;
#Override
public void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.anonymous()
.disable()
.addFilterAt(new JWTAuthorizationFilter(userRepository), BasicAuthenticationFilter.class)
.logout().clearAuthentication(true).logoutUrl("/logout").logoutSuccessUrl("/login").deleteCookies("JSESSIONID").invalidateHttpSession(true)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http401ForbiddenEntryPoint());
}
#Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/login/**");
}
}```
I have the following Spring security configuration class for two separate security realms, the admin area and the frontend area:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsServiceImpl userDetailsService;
#Configuration
#Order(1)
public static class AdminAreaConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private AuthSuccessAdmin authSuccessAdmin;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new AntPathRequestMatcher("/admin/**"))
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/login/login.html").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/admin/login.html")
.permitAll()
.successHandler(authSuccessAdmin)
.and()
.logout()
.permitAll();
}
}
#Configuration
#Order(2)
public static class UserAreaConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private AuthSuccessFrontend authSuccessFrontend;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new AntPathRequestMatcher("/**"))
.csrf().disable()
.authorizeRequests()
.antMatchers("/about", "/register").permitAll()
.antMatchers("/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.successHandler(authSuccessFrontend)
.and()
.logout()
.permitAll();
}
}
}
When the app is started, the authentication success handler of the admin area is overwritten by the authentication handler of the frontend area, which is loaded after the first. This results in a wrong redirect when logging into the admin area (redirects to url defined in the frontend auth success handler). How can I assign disctinct handlers to the separate configurations?
The issue seems to be in RequestMatcher pattern.
Your USER app has the RequestMatcher pattern '/**'(means anything after / which will include path /admin as well) which will override your ADMIN RequestMatcher pattern /admin/**
Change the user RequestMatcher to /user/**
I have two different users in my web app: client and translator. I created two different HttpSecurity configuration for this. I have super class for both configurations:
#Configuration
#ComponentScan(basePackages = {"ua.translate"})
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
CustomSuccessHandler customSuccessHandler;
#Autowired
#Qualifier("customAccessDeniedHandler")
AccessDeniedHandler accessDeniedHandler;
#Autowired
DataSource dataSource;
#Autowired
PersistentTokenRepository tokenRepository;
#Override
public void configure(WebSecurity web){
web
.ignoring()
.antMatchers(new String[]{"/resources/**"});
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth,#Qualifier("detailsService") UserDetailsService uds) throws Exception{
auth.userDetailsService(uds)
.passwordEncoder(bcryptEncoder());
}
#Bean
public PasswordEncoder bcryptEncoder(){
return new BCryptPasswordEncoder();
}
#Autowired
#Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices(#Qualifier("detailsService") UserDetailsService uds) {
PersistentTokenBasedRememberMeServices tokenBasedservice = new PersistentTokenBasedRememberMeServices(
"remember-me", uds, tokenRepository);
return tokenBasedservice;
}
#Bean
public SavedRequestAwareAuthenticationSuccessHandler
savedRequestAwareAuthenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandler auth
= new SavedRequestAwareAuthenticationSuccessHandler();
auth.setTargetUrlParameter("targetUrl");
return auth;
}
}
There are two different configurations for different users:
#Configuration
#EnableWebSecurity
public class AppSecurityConfigGlobal{
#Configuration
#Order(1)
public static class AppSecurityConfigTranslator extends AppSecurityConfig{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/translator/**")
.authorizeRequests()
.antMatchers("/translator/registration*","/bulbular*").anonymous()
.antMatchers("/translator/index","/translator/login*").permitAll()
.antMatchers("/translator/**").hasRole("TRANSLATOR")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/translator/login")
.permitAll()
.successHandler(customSuccessHandler)
.failureUrl("/translator/login?error")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check")
.and()
.logout().deleteCookies("JSESSIONID")
.logoutUrl("/translator/logout")
.logoutSuccessUrl("/translator/login?logout")
.and()
.rememberMe().tokenRepository(tokenRepository)
.tokenValiditySeconds(86400)
.and()
.csrf()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
}
#Configuration
#Order(2)
public static class AppSecurityConfigClient extends AppSecurityConfig{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/client/registration*","/bulbular*").anonymous()
.antMatchers("/client/**").hasRole("CLIENT")
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/index","/translators","/orders","/client/login*").permitAll()
.and()
.formLogin()
.loginPage("/client/login")
.permitAll()
.successHandler(customSuccessHandler)
.failureUrl("/client/login?error")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check")
.and()
.logout().deleteCookies("JSESSIONID")
.logoutUrl("/client/logout")
.logoutSuccessUrl("/client/login?logout")
.and()
.rememberMe().tokenRepository(tokenRepository)
.tokenValiditySeconds(86400)
.and()
.csrf()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
}
}
My problem is when user with ROLE_CLIENT logged out, he is redirected to ../client/login and no message about successful logging out not displayed.
But when user with ROLE_TRANSLATOR logged out, he is redirected to ../translator/login?logout and message is showed, so there is no problem.
I don't understand cause of this problem, help me, please)
I found cause of this problem! In my configuration for client I has:
.antMatchers("/client/registration*","/bulbular*").anonymous()
.antMatchers("/client/**").hasRole("CLIENT")
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/index","/translators","/orders","/client/login*").permitAll()
but one rule for order of andMatchers(..) in configuration is: the most strict andMatchers must be last.
I changed order:
.antMatchers("/client/registration*","/bulbular*").anonymous()
.antMatchers("/index","/translators","/orders","/client/login*").permitAll()
.antMatchers("/client/**").hasRole("CLIENT")
.antMatchers("/admin/**").hasRole("ADMIN")
And problem is solved!)
Anyone knows how to configure a customized 403 page in spring security? Looking in the web, all the results I get it's with XML configuration, and I am using Java configuration. That's my SecurityConfig:
#Configuration
#ComponentScan(value="com")
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return new CustomAuthenticationManager();
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/resources/**", "/publico/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/acesso/login").permitAll()
.loginProcessingUrl("/login").permitAll()
.usernameParameter("login")
.passwordParameter("senha")
.successHandler(new CustomAuthenticationSuccessHandler())
.failureHandler(new CustomAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/acesso/login").permitAll();
}
}
I have a custom implementation for AccessDeniedHandler too:
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException arg2) throws IOException, ServletException {
response.sendRedirect(request.getContextPath() + "/erro/no_permit");
}
}
If I'm right, to personalize the page 403, you could use the model implemented by this server.
Spring Security : Customize 403 Access Denied Page
Example:
AppConfig.java
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/")
.and()
.rememberMe()
.and()
.csrf().disable();
}
HomeController.java
#RequestMapping("/403")
public String accessDenied() {
return "errors/403";
}
And the .html, would be a custom page with some message 403.