Spring Security在登录后始终返回403 accessDeniedPage

我是Spring的新手,我一直在尝试使用spring security实现一个简单的登录页面。 但它总是在提供登录凭据后访问Denied url。 在我提供正确的用户名和密码后,loadUserByUsername()方法始终返回用户。 但我不知道如何找到返回用户对象后发生的事情。

用户只有一个角色。 该方法返回具有SUPER_USER角色的用户。

这是我的spring安全配置类

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @ComponentScan(basePackageClasses = AppConfig.class) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired UserDetailsService userDetailsService; @Autowired public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { System.out.println("Inside configureGlobalSecurity method"); auth.userDetailsService(userDetailsService); auth.authenticationProvider(authenticationProvider()); } @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("Inside configure method"); http.authorizeRequests().antMatchers("/", "/list") .access("hasRole('SUPER_USER') or hasRole('NORMAL_USER') or hasRole('CUSTOMER')") .and().formLogin().loginPage("/login") .loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password").and() .csrf().and().exceptionHandling().accessDeniedPage("/Access_Denied"); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public DaoAuthenticationProvider authenticationProvider() { System.out.println("Inside authenticationProvider method"); DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder()); return authenticationProvider; } @Bean public AuthenticationTrustResolver getAuthenticationTrustResolver() { return new AuthenticationTrustResolverImpl(); } } 

这是我的UserDetailsS​​erviceImpl类

 import java.util.HashSet; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.dao.user.UserDao; import com.entity.user.User; @Service("userDetailsService") @Transactional public class UserDetailsServiceImpl implements UserDetailsService { @Autowired UserDao userDao = null; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userDao.getUserByUsername(username); if(user!=null) { Set grantedAuthorities = new HashSet(); grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getDescription().getStringVal())); org.springframework.security.core.userdetails.User u = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), true, true, true, true,grantedAuthorities); return u; } else { throw new UsernameNotFoundException("User Does not Exist"); } } } 

在我提供正确的用户名和密码后,此方法始终返回用户。这是它返回的内容

 org.springframework.security.core.userdetails.User@a3b: Username: RM; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SUPER_USER 

这是Controller类

 import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/") public class LoginController { @Autowired AuthenticationTrustResolver authenticationTrustResolver; @RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET) public String listUsers(ModelMap model) { System.out.println("Inside controller list"); return "first"; } @RequestMapping(value = "/Access_Denied", method = RequestMethod.GET) @ResponseBody public String accessDeniedPage(ModelMap model) { return "Access Dennied"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String loginPage() { System.out.println("Inside controller login"); if (isCurrentAuthenticationAnonymous()) { return "login"; } else { return "redirect:/list"; } } @RequestMapping(value="/logout", method = RequestMethod.GET) public String logoutPage (HttpServletRequest request, HttpServletResponse response){ Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null){ SecurityContextHolder.getContext().setAuthentication(null); } return "redirect:/login?logout"; } /** * This method returns true if users is already authenticated [logged-in], else false. */ private boolean isCurrentAuthenticationAnonymous() { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return authenticationTrustResolver.isAnonymous(authentication); } 

这是我的登录表单

  

Userme,您如何为Security的UserDetails对象构建角色名称?

请注意,根据Spring Security的架构决策,您必须在“权限”前加上“ROLE_”:

 new SimpleGrantedAuthority("ROLE_" + roleName); 

ATT