How to check “hasRole” in Java Code with Spring Security?

前端 未结 18 1543
梦毁少年i
梦毁少年i 2020-11-28 20:54

How to check user authority or permission in Java Code ? For example - I want to show or hide button for user depending on role. There are annotations like:

         


        
相关标签:
18条回答
  • 2020-11-28 21:07

    User Roles can be checked using following ways:

    1. Using call static methods in SecurityContextHolder:

      Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //do something}

    2. Using HttpServletRequest

    @GetMapping("/users")
    public String getUsers(HttpServletRequest request) {
        if (request.isUserInRole("ROLE_NAME")) {
          
        }

    0 讨论(0)
  • 2020-11-28 21:08

    Strangely enough, I don't think there is a standard solution to this problem, as the spring-security access control is expression based, not java-based. you might check the source code for DefaultMethodSecurityExpressionHandler to see if you can re-use something they are doing there

    0 讨论(0)
  • 2020-11-28 21:12

    Most answers are missing some points:

    1. Role and authority are not the same thing in Spring. See here for more details.

    2. Role names are equal to rolePrefix + authority.

    3. The default role prefix is ROLE_, however, it is configurable. See here.

    Therefore, a proper role check needs to respect the role prefix if it is configured.

    Unfortunately, the role prefix customization in Spring is a bit hacky, in many places the default prefix, ROLE_ is hardcoded, but in addition to that, a bean of type GrantedAuthorityDefaults is checked in the Spring context, and if it exists, the custom role prefix it has is respected.

    Bringing all this information together, a better role checker implementation would be something like:

    @Component
    public class RoleChecker {
    
        @Autowired(required = false)
        private GrantedAuthorityDefaults grantedAuthorityDefaults;
    
        public boolean hasRole(String role) {
            String rolePrefix = grantedAuthorityDefaults != null ? grantedAuthorityDefaults.getRolePrefix() : "ROLE_";
            return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                    .map(Authentication::getAuthorities)
                    .map(Collection::stream)
                    .orElse(Stream.empty())
                    .map(GrantedAuthority::getAuthority)
                    .map(authority -> rolePrefix + authority)
                    .anyMatch(role::equals);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 21:13

    My Approach with the help of Java8 , Passing coma separated roles will give you true or false

        public static Boolean hasAnyPermission(String permissions){
        Boolean result = false;
        if(permissions != null && !permissions.isEmpty()){
            String[] rolesArray = permissions.split(",");
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            for (String role : rolesArray) {
                boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
                if (hasUserRole) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
    
    0 讨论(0)
  • 2020-11-28 21:14

    You can retrieve the security context and then use that:

        import org.springframework.security.core.Authentication;
        import org.springframework.security.core.GrantedAuthority;
        import org.springframework.security.core.context.SecurityContext;
        import org.springframework.security.core.context.SecurityContextHolder;
    
        protected boolean hasRole(String role) {
            // get security context from thread local
            SecurityContext context = SecurityContextHolder.getContext();
            if (context == null)
                return false;
    
            Authentication authentication = context.getAuthentication();
            if (authentication == null)
                return false;
    
            for (GrantedAuthority auth : authentication.getAuthorities()) {
                if (role.equals(auth.getAuthority()))
                    return true;
            }
    
            return false;
        }
    
    0 讨论(0)
  • 2020-11-28 21:15

    You can get some help from AuthorityUtils class. Checking role as a one-liner:

    if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
        /* ... */
    }
    

    Caveat: This does not check role hierarchy, if such exists.

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