Spring security: Redirect unauthorised url - spring

#PreAuthorize("hasPermission(#id,'Integer','write')")
#RequestMapping(value="events/{id}/edit",method=RequestMethod.GET)
public String edit(Model model,#PathVariable("id") int id) {
model.addAttribute("event", eventService.getEvent(id));
return "events/edit";
}
Security config
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/", "/index", "/register", "/regitrationConfirm", "/forgotPassword", "/accountRecovery", "/passwordReset", "/public/**").permitAll()
.antMatchers(HttpMethod.POST, "/register", "/accountRecovery","/passwordReset").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginPage("/login?error")
.permitAll()
.failureHandler(authFailureHandler)
.and()
.rememberMe()
.tokenValiditySeconds(3600)
.key("rememberTracker")
.and()
.logout()
.permitAll()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login?expired");
}
}
i want to redirect or show a custom page to the user if authorization fails. Is there a way to that?
updated with spring security code.
Thanks

I updated you SecurityConfig to add a failureUrl and successHandler
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/", "/index", "/register", "/regitrationConfirm", "/forgotPassword", "/accountRecovery", "/passwordReset", "/public/**").permitAll()
.antMatchers(HttpMethod.POST, "/register", "/accountRecovery","/passwordReset").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginPage("/login?error")
.permitAll()
.failureUrl("/your-unsuccessful-authentication-url-here")
.successHandler(yourSuccesshandler) //create your success handler to redirect the user to different places depending on his role
//.failureHandler(authFailureHandler) I deleted this line, we just need a redirect
.and()
.rememberMe()
.tokenValiditySeconds(3600)
.key("rememberTracker")
.and()
.logout()
.permitAll()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login?expired");
}
}
The success Handler
public class SuccessAuthenticationHandler implements AuthenticationSuccessHandler{
public SuccessAuthenticationHandler(){
}
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth) throws IOException, ServletException {
HttpSession session = request.getSession();
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String redirect = "";
if(user != null){
session.setAttribute("username", user.getUsername());
if(user.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))
|| user.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN")))
redirect = "admin/";
else if(user.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_YOUR_ROLE")))
redirect = "yourrole/";
}
if(redirect.isEmpty())
redirect = "signin";
response.sendRedirect(redirect);
}
}

Related

adding a login page before swagger-ui.html using thyme leaf and spring Boot

#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.authorizeRequests()
.antMatchers("/", "/favicon.ico", "/**/*.png", "/**/*.gif", "/**/*.svg", "/**/*.jpg",/**/*.html","/**/*.css", "/**/*.js")
.permitAll()
.antMatchers("/v2/api-docs", "/configuration/ui", "/configuration/security","/webjars/**")
.permitAll().antMatchers("/swagger-resources","/swagger-resources/configuration/ui","/swagger-ui.html").hasRole("SWAG").anyRequest().authenticated()
.antMatchers("/api/all/**").permitAll().antMatchers("/api/Service/**").permitAll()
.antMatchers("/api/Service/Package/**").permitAll()
.antMatchers("api/public/customer/**").hasRole("CUSTOMER1")
.antMatchers(HttpMethod.OPTIONS).permitAll().anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.addFilterBefore(authTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("manager").password("{noop}password").roles("MANAGER");
}
#Controller
public class HomeController {
#GetMapping("/")
public String root() {
return "index";
}
#GetMapping("/user")
public String userIndex() {
return "swagger-ui.html";
}
#GetMapping("/login")
public String login() {
return "login";
}
#GetMapping("/access-denied")
public String accessDenied() {
return "/error/access-denied";
}
}
so iam trying to authenticate /swagger-ui.html like a simple popup login using inmemory in order to access the api by certain users
when i do with this code i got the following output of the attached image
when i login there is no redirection for authentication
>

Spring security root authentication

I have a simple WebSecurityConfiguration configuration class that defines how my application works on a security level.
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/register", "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.passwordParameter("password")
.usernameParameter("emailAddress")
.successHandler(authenticationSuccessHandler())
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.permitAll()
.and()
.httpBasic();
}
#Bean
public SavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler() {
return new SavedRequestAwareAuthenticationSuccessHandler();
}
}
I also have a #Controller which defined two simple endpoints
#Controller
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getHome() {
return "home";
}
#RequestMapping(value = "/test", method = RequestMethod.GET)
public void testEndpoint() throws CreateException {
return "test";
}
}
When load up the application and navigate to localhost:8080/test I am redirected to the login form as expected. However when I navigate to localhost:8080/ or localhost:8080 (no forwardslash) I am shown the "home" page where I would have expected to have been redirected to localhost:8080/login.
I have tried changing the .antMatcher("/**") to .antMatcher("**") but this doesn't have the desired effect either.
The issue is that one the .formLogin() and .logout() they have been ended with a .permitAll(). This allowed the root localhost:8080 to pass through without being authenticated.
By removing them it has solved the issue.

Configure Spring Security for multiple login pages in a Spring Boot application

#Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AccessDeniedHandler accessDeniedHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home", "/about").permitAll()
.antMatchers("/admin/**").hasAnyRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN");
}
}
The Security Configuration is working fine as expected. Now I am trying to implement 2 login forms each for Admin and User. I tried separating the configuration using #Order but landed on the issue mentioned here Spring boot and spring security multiple login pages
Any better approach to implement the same?
In order to configure two different http elements, let’s create two static classes annotated with #Configuration that extend the WebSecurityConfigurerAdapter. Try configuring something like this:
#Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AccessDeniedHandler accessDeniedHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin*")
.authorizeRequests()
.anyRequest()
.hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/loginAdmin")
.loginProcessingUrl("/admin_login")
.failureUrl("/loginAdmin?error=loginError")
.defaultSuccessUrl("/adminPage")
.and()
.logout()
.logoutUrl("/admin_logout")
.logoutSuccessUrl("/protectedLinks")
.deleteCookies("JSESSIONID")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf().disable();
}
}
And, for normal users:
#Configuration
#Order(2)
public static class SpringSecurityConfig2 extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user*")
.authorizeRequests()
.anyRequest()
.hasRole("USER")
.and()
.formLogin()
.loginPage("/loginUser")
.loginProcessingUrl("/user_login")
.failureUrl("/loginUser?error=loginError")
.defaultSuccessUrl("/userPage")
.and()
.logout()
.logoutUrl("/user_logout")
.logoutSuccessUrl("/protectedLinks")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf().disable();
}
}
Refer http://www.baeldung.com/spring-security-two-login-pages

spring boot security login redirects to / when contextPath set

I've got this working when no contextPath is set. But when I set server.contextPath in application.properties, happens that when logging in http://localhost:8080/t2debt_site/login the page redirects to http://localhost:8080/login. What can be happening, please help!
private static final String[] UNSECURED_RESOURCE_LIST =
new String[]{"/", "/resources/**", "/static/**", "/css/**", "/webjars/**",
"/img/**", "/js/**"};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(UNSECURED_RESOURCE_LIST).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.failureUrl("/login?error")
.usernameParameter("email")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("remember-me")
.logoutSuccessUrl("/login")
.permitAll()
.and()
.rememberMe();
}
#Override
public void configure(WebSecurity security) {
//security.ignoring().antMatchers("/css/**","/img/**","/js/**");
//security.ignoring().antMatchers("/static/**");
security.ignoring().antMatchers(UNSECURED_RESOURCE_LIST);
//security.ignoring().antMatchers("/resources/**");
}

Spring Boot Security Login

My enhanced Pet Clinic application requires security.
I want to have the following:
Login form - WORKING
HTTPS - WORKING
HTTP requests redirecting to HTTPS - not sure how to do this
HTTP static resources - not sure if this is really necessary
Any advice would be welcome.
My application can be found at https://github.com/arnaldop/enhanced-pet-clinic.
Here's code from my WebSecurityConfigurerAdapter subclass:
private static final String[] UNSECURED_RESOURCE_LIST =
new String[] {"/", "/resources/**", "/assets/**", "/css/**", "/webjars/**",
"/images/**", "/dandelion-assets/**", "/unauthorized", "/error*"};
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(UNSECURED_RESOURCE_LIST);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
//#formatter:off
http
.authorizeRequests()
.antMatchers(UNSECURED_RESOURCE_LIST)
.permitAll()
.antMatchers("/owners/**", "/vets/**", "/vets*").hasRole("USER")
.antMatchers("/manage/**").hasRole("ADMIN")
.anyRequest()
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.requiresChannel()
.antMatchers("/login", "/owners/**", "/vets/**", "/vets*", "/manage/**")
.requiresSecure()
.and()
.exceptionHandling()
.accessDeniedPage("/router?q=unauthorized")
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login?expired")
;
//#formatter:on
}
Thanks!
For "HTTP requests redirecting to HTTPS - not sure how to do this"
we will need to add the TomcatEmbeddedServletContainerFactory bean to one of our #Configuration classes.
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
for more information please refer this link

Resources