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.
Related
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 am making enterprise webapp, i have built my custom login page but somehow only spring security login page is coming instead of my custom login page. Below is my security configuration class.
please help.
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("test").password("pwd123")
.roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/", "/*todo*/**").access("hasRole('USER')").and()
.formLogin();
http.csrf().disable();
}
You have to specify the url to your custom login page.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/", "/*todo*/**").access("hasRole('USER')").and()
.formLogin()
// put the relative URL to your custom login here
.loginPage("/login")
.permitAll();
http.csrf().disable();
}
Hope this helps.
Look every thing good, this is work for me:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/todo/**").hasRole("USER")
.antMatchers("/", "/home").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/home")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
Here is a Spring Boot project.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout=true")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
Reference : https://devkonline.com/tutorials/content/SPRING-SECURITY-5-CUSTOM-FORM-LOGIN-THYMELEAF
I have struggling to configure security for some different paths I have.
I would like this structure:
/actuator/health <-- open
/api/** <-- hasAnyAuthority
/auth/** <-- basic authentication
all others no access
So far this is what I have
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**") // If you want to override the security provided by Spring Boot.
.addFilter(preAuthFilter())
.cors()
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/api/**").hasAnyAuthority("something")
.antMatchers("/auth/**").authenticated()
.and()
.httpBasic();
}
I would like to add .anyRequest().denyAll() but that doesn't seem to be possible after httpBasic().
Can anyone confirm that the above code will be the same as what I would like?
Example on how to split configuration by path:
#Configuration
public class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/public/**", "/api/register").anonymous() //if you need to allow some path in api
.antMatchers("/api/**", "/api/register/**").hasRole("API_USER")
.and()
.formLogin()
.loginPage("/api/")
.failureHandler(failureHandler())
.loginProcessingUrl("/api/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessUrl("/api/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/api/loginfailed");
}
}
Second path:
#Configuration
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/auth/**")
.authorizeRequests()
.antMatchers("/auth/register").anonymous()
.antMatchers("/auth/**", "/auth/register/**").hasRole("USER")
.and()
.formLogin()
.loginPage("/auth/")
.failureHandler(failureHandler())
.loginProcessingUrl("/auth/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/auth/logout")
.logoutSuccessUrl("/auth/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/auth/loginfailed");
}
}
Now since you have not added security for /actuator/health you can either leave it without one or you can make another adapter for it and permit access to everyone.
Also you should use csrf protection, it is easy to implement.
I am getting 403 on every request having pattern /admin
I need to restrict /admin only for admin role.
Failed approach :
Tried using #PreAuthorize(hasRole('ADMIN')) and #PreAuthorize(hasRole('ROLE_ADMIN')) on controller but no luck.
Tried removing #PreAuthorize from controller and adding pattern in the below class with hasRole but no luck
Below is the class extends WebSecurityConfigurerAdapter
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
AuthenticationEntryPoint authenticationEntryPoint;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET,"/admin/**").hasAnyRole("ADMIN","ADMIN_TENANT")
.anyRequest().authenticated()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
httpSecurity.
addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.
headers().cacheControl().disable();
}
Already tried solutions mentioned in similar question but no luck.
So please don't mark it duplicate.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
AuthenticationEntryPoint authenticationEntryPoint;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET,"/admin/**").hasAnyRole("ADMIN","ADMIN_TENANT") // change hasAnyrole to hasAnyAuthority
.anyRequest().authenticated()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
httpSecurity.
addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.
headers().cacheControl().disable();
}
My similar Git Project: here
// Config to check if already active
http.authorizeRequests()
.and()
.rememberMe()
.tokenRepository(new JdbcTokenRepositoryImpl().setDataSource(//datasource_name) )
.tokenValiditySeconds(//TimeInterval in sec);
}
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!)