Reputation: 73
I'm new to spring security method. I'm trying to implement two user's in my web application. (Admin Role & User Role) I have two re-directions pages using thymeleaf for admin it should drop to /admin/** and for users it should be /user/**
I've tried adding two spring security class using @order(1) and order(2) but still not working.. my aim is if the user logins and has roles in my security it should redirect to the correct pages.
Please see my code below
spring.queries.users-query=select email, password, enabled from user where email=?
spring.queries.roles-query=select u.email, r.role from user u inner join user_role ur on (u.id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/confirm").permitAll()
.antMatchers("/forgotpassword").permitAll()
.antMatchers("/criminal/getAllWantedCriminal").permitAll()
.antMatchers("/criminal/viewCriminal").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/admin/home")
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied");
}
Upvotes: 0
Views: 2308
Reputation: 6444
The easiest way to achieve this is creating a custom org.springframework.security.web.authentication.AuthenticationSuccessHandler
There, once the user has correctly logged in, you could just check wether the
Authentication object has ROLE_ADMIN
to redirect to default configured success url (the default user success url) or to the admin one. This is a working sample, extending org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
public class RoleBasedAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
private String adminRoleTargetUrl;
private String adminRoleAuthority;
/**
* @param defaultTargetUrl
*/
public RoleBasedAuthenticationSuccessHandler(String defaultTargetUrl, String adminRoleTargetUrl, String adminRoleAuthority) {
super(defaultTargetUrl);
this.adminRoleTargetUrl = adminRoleTargetUrl;
this.adminRoleAuthority = adminRoleAuthority;
}
/* (non-Javadoc)
* @see org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if(isAdmin(authentication)){
this.getRedirectStrategy().sendRedirect(request, response, this.getAdminRoleTargetUrl());
return;
}
super.onAuthenticationSuccess(request, response, authentication);
}
/**
* @param authentication
*/
protected boolean isAdmin(Authentication authentication) {
for(GrantedAuthority authority : authentication.getAuthorities()){
if(authority.getAuthority().equals(this.getAdminRoleAuthority())){
return true;
}
}
return false;
}
/**
* @return the adminRoleTargetUrl
*/
public String getAdminRoleTargetUrl() {
return adminRoleTargetUrl;
}
/**
* @return the adminRoleAuthority
*/
public String getAdminRoleAuthority() {
return adminRoleAuthority;
}
}
Then, change your security config class in order to set the RoleBasedAuthenticationSuccessHandler
instance in method successHandler
instead of using defaultSuccessUrl
:
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/confirm").permitAll()
.antMatchers("/forgotpassword").permitAll()
.antMatchers("/criminal/getAllWantedCriminal").permitAll()
.antMatchers("/criminal/viewCriminal").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.successHandler(this.getSuccessHandler())
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied");
}
private AuthenticationSuccessHandler getSuccessHandler() {
return new RoleBasedAuthenticationSuccessHandler(
"/user/home",
"/admin/home",
"ROLE_ADMIN"
);
}
Upvotes: 1