Springboot Security hasRole not working

前端 未结 2 791
执笔经年
执笔经年 2020-11-22 08:53

I’m unable to use hasRole method in @PreAuthorize annotation. Also request.isUserInRole(“ADMIN”) gives false. What am I m

相关标签:
2条回答
  • 2020-11-22 09:25

    i had to improvise a little, maybe there is other ways simpler then mine, but at the time i worked on this i had no other choice but to improvise a bit, after a thorough research came up with this solution. spring security has an interface called AccessDecisionManager, you will need to implement it.

    @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;
        }
    }
    

    now to support this custom access-decision-manager with your security config do this in the security configuration

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

    accessDecisionManager is the autowired bean of the AccessDecisionManager implementation you've created.

    0 讨论(0)
  • 2020-11-22 09:30

    You have to name your authority with prefix ROLE_ to use isUserInRole, see Spring Security Reference:

    The HttpServletRequest.isUserInRole(String) will determine if SecurityContextHolder.getContext().getAuthentication().getAuthorities() contains a GrantedAuthority with the role passed into isUserInRole(String). Typically users should not pass in the "ROLE_" prefix into this method since it is added automatically. For example, if you want to determine if the current user has the authority "ROLE_ADMIN", you could use the following:

    boolean isAdmin = httpServletRequest.isUserInRole("ADMIN");
    

    Same for hasRole (also hasAnyRole), see Spring Security Reference:

    Returns true if the current principal has the specified role. By default if the supplied role does not start with 'ROLE_' it will be added. This can be customized by modifying the defaultRolePrefix on DefaultWebSecurityExpressionHandler.

    0 讨论(0)
提交回复
热议问题