Reputation: 1751
I am just working on the Spring security with role based login. While I am getting everything fine, but the problem comes if after sucessfull login i want to redirect to the admin page, its giving me forbidden error. Still not getting any clue whatsoever where its going wrong.
The snippet is as follows:
@Configuration
@EnableWebSecurity
public class UserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
CustomSuccessHandler customSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("in configure");
http.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home", "/about").permitAll()
.antMatchers("/admin").hasAnyRole("ADMIN") // if changed to antMatchers("/admin").permitAll() then it works fine
.antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.successHandler(customSuccessHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.permitAll();
}
CustomSucessHandler.Java
@Component
public class CustomSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
System.out.println("Can't redirect");
return;
}
System.out.println("Return URL : "+targetUrl);
redirectStrategy.sendRedirect(request, response, targetUrl);
}
/*
* This method extracts the roles of currently logged-in user and returns
* appropriate URL according to his/her role.
*/
protected String determineTargetUrl(Authentication authentication) {
String url = "";
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
List<String> roles = new ArrayList<String>();
System.out.println("authoritirs "+authorities.size());
for (GrantedAuthority a : authorities) {
System.out.println(a.getAuthority());
roles.add(a.getAuthority());
}
if (isDba(roles)) {
url = "/db";
} else if (isAdmin(roles)) {
url = "/admin";
} else if (isUser(roles)) {
url = "/home";
} else {
url = "/accessDenied";
}
return url;
}
private boolean isUser(List<String> roles) {
if (roles.contains("USER")) {
return true;
}
return false;
}
private boolean isAdmin(List<String> roles) {
if (roles.contains("ADMIN")) {
return true;
}
return false;
}
private boolean isDba(List<String> roles) {
if (roles.contains("DBA")) {
return true;
}
return false;
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
Whenever i am logging from the login.jsp page , the user authentication is working properly, after the user authentication the page should redirect to the admin page based on the user role where the code for redirection has been written in the CustomSuceessandler. The targetUrl in CustomSuccessHandler is also printing the url as "/admin" but i am getting the Forbidden 403 error in the browser.
If I comment the code or modify the code in UserSecurityConfig as .antMatchers("/admin").permitAll() instead of .antMatchers("/admin").hasAnyRole("ADMIN")
then it works fine and gets redirected to admin page.
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback. Sun Nov 25 23:58:01 IST 2018 There was an unexpected error (type=Forbidden, status=403). Forbidden
Upvotes: 0
Views: 1023
Reputation: 1027
You got forbidden because hasAnyRole("ADMIN")
will add a ROLE_ prefix to the given string and so the check ROLE_ADMIN against ADMIN fails. Use hasAuthority("ADMIN")
instead or rename the authority to ROLE_ADMIN to fix it.
Upvotes: 1