Springboot Security hasRole无法正常工作

时间:2017-01-30 22:23:57

标签: spring-boot spring-security

我无法在hasRole注释中使用@PreAuthorize方法。 request.isUserInRole(“ADMIN”) false也会.hasAuthority(“ADMIN”)。我错过了什么? 虽然 UPDATE | v LSTM_t-LSTM_t+1-LSTM_t+2 LSTM_t+3-LSTM_t+4-LSTM_t+5 .... | | | | | | x_t x_t+1 x_t+2 x_t+3 x_t+4 x_t+5 工作正常。

我正在从数据库为用户分配权限。

3 个答案:

答案 0 :(得分:20)

您必须使用前缀ROLE_命名您的权限才能使用isUserInRole,请参阅Spring Security Reference

  

HttpServletRequest.isUserInRole(String)将确定SecurityContextHolder.getContext().getAuthentication().getAuthorities()是否包含角色传递到GrantedAuthority的{​​{1}}。通常,用户不应将“ROLE_”前缀传递给此方法,因为它会自动添加。例如,如果要确定当前用户是否具有“ROLE_ADMIN”权限,则可以使用以下命令:

     
isUserInRole(String)

boolean isAdmin = httpServletRequest.isUserInRole("ADMIN"); (也是hasRole)相同,请参阅Spring Security Reference

  

如果当前主体具有指定的角色,则返回hasAnyRole。默认情况下,如果提供的角色不以“ROLE_”开头,则会添加该角色。这可以通过修改true上的defaultRolePrefix来自定义。

答案 1 :(得分:0)

我不得不即兴创作一些,也许还有其他比我更简单的方法,但是当我对此进行彻底研究后,当时我除了进行其他工作外别无选择。 Spring Security有一个名为AccessDecisionManager的接口,您将需要实现它。

@Component
public class RolesAccessDecisionManager implements AccessDecisionManager {
    private final static String AUTHENTICATED = "authenticated";
    private final static String PERMIT_ALL = "permitAll";

    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        collection.forEach(configAttribute -> {
            if (!this.supports(configAttribute))
                throw new AccessDeniedException("ACCESS DENIED");
        });
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated()) {
            String rolesAsString = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(","));
            if (configAttribute.toString().contains(rolesAsString))
                return true;
            else
                return (configAttribute.toString().contains(PERMIT_ALL) || configAttribute.toString().contains(AUTHENTICATED));
        }
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

现在要在您的安全配置中支持此自定义访问决定管理器,请在安全配置中执行此操作

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
// other configs
    .accessDecisionManager(this.accessDecisionManager)

accessDecisionManager是您创建的AccessDecisionManager实现的自动装配的bean。

答案 2 :(得分:0)

您可以使用 hasRole() 或 hasAuthority()。 不同之处在于,您必须为 hasAusthority() 方法使用 ROLE_。 所以对于 ROLE_ADMIN,

 @PreAuthorize("hasRole('ADMIN')") == @PreAuthorize("hasAuthority('ROLE_ADMIN')")