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

前端 未结 18 1542
梦毁少年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:18

    I'm using this:

    @RequestMapping(method = RequestMethod.GET)
    public void welcome(SecurityContextHolderAwareRequestWrapper request) {
        boolean b = request.isUserInRole("ROLE_ADMIN");
        System.out.println("ROLE_ADMIN=" + b);
    
        boolean c = request.isUserInRole("ROLE_USER");
        System.out.println("ROLE_USER=" + c);
    }
    
    0 讨论(0)
  • 2020-11-28 21:21

    In our project, we are using a role hierarchy, while most of the above answers only aim at checking for a specific role, i.e. would only check for the role given, but not for that role and up the hierarchy.

    A solution for this:

    @Component
    public class SpringRoleEvaluator {
    
    @Resource(name="roleHierarchy")
    private RoleHierarchy roleHierarchy;
    
    public boolean hasRole(String role) {
        UserDetails dt = AuthenticationUtils.getSessionUserDetails();
    
        for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
            if (auth.toString().equals("ROLE_"+role)) {
                return true;
            }
        }
        return false;
    }
    

    RoleHierarchy is defined as a bean in spring-security.xml.

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

    This is sort of coming at the question from the other end but I thought I'd throw it in as I really had to dig on the internet to find this out.

    There is a lot of stuff about how to check roles but not much saying what you are actually checking when you say hasRole("blah")

    HasRole checks the granted authorities for the currently authenticated principal

    So really when you see hasRole("blah") really means hasAuthority("blah").

    In the case I've seen, you do this with a class that Implements UserDetails which defines a method called getAuthorities. In this you'll basically add some new SimpleGrantedAuthority("some name") to a list based on some logic. The names in this list are the things checked by the hasRole statements.

    I guess in this context the UserDetails object is the currently authenticated principal. There's some magic that happens in and around authentication providers and more specifically the authentication-manager that makes this happen.

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

    Instead of using a loop to find the authority from UserDetails you can do:

    Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
    boolean authorized = authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
    
    0 讨论(0)
  • 2020-11-28 21:23

    The answer from JoseK can't be used when your in your service layer, where you don't want to introduce a coupling with the web layer from the reference to the HTTP request. If you're looking into resolving the roles while in the service layer, Gopi's answer is the way to go.

    However, it's a bit long winded. The authorities can be accessed right from the Authentication. Hence, if you can assume that you have a user logged in, the following does it:

    /**
     * @return true if the user has one of the specified roles.
     */
    protected boolean hasRole(String[] roles) {
        boolean result = false;
        for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
            String userRole = authority.getAuthority();
            for (String role : roles) {
                if (role.equals(userRole)) {
                    result = true;
                    break;
                }
            }
    
            if (result) {
                break;
            }
        }
    
        return result;
    }
    
    0 讨论(0)
  • 2020-11-28 21:24

    This two annotation below is equal, "hasRole" will auto add prefix "ROLE_". Make sure you have the right annotation. This role is set in UserDetailsService#loadUserByUsername.

    @PreAuthorize("hasAuthority('ROLE_user')")
    @PreAuthorize("hasRole('user')")
    

    then, you can get the role in java code.

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
        System.out.println("user role2");
    }
    
    0 讨论(0)
提交回复
热议问题