Spring Security Role Hierarchy not working using Java Config

前端 未结 6 2135
轻奢々
轻奢々 2021-01-04 21:48

First of all, I am new to Java Spring Framework. So forgive me if I did not provide enough info. I have tried to add RoleHierarchy into my app but it did not work. Below are

6条回答
  •  青春惊慌失措
    2021-01-04 21:55

    I don't use Spring RoleHierarchy - because it doea not work for me. But Ussualy I do like this: Define Role interface

    public static interface Role {
      String getName();
      List getHierarchy();
    }
    

    List of my roles (to store in DB):

    public interface AuthStates {
      // Spring security works fine only with ROLE_*** prefix
      String ANONYMOUS = "ROLE_ANONYMOUS";
      String AUTHENTICATED = "ROLE_AUTHENTICATED";
      String ADMINISTRATOR = "ROLE_ADMINISTRATOR";
    }
    

    Define Anonymous role as basic role class:

    public static class Anonymous implements Role {
      private final String name;
      private final List hierarchy = Lists.newArrayList(ANONYMOUS);
    
      public Anonymous() {
        this(ANONYMOUS);
      }
    
      protected Anonymous(String name) {
        this.name = name;
      }
    
      @Override
      public String getName() {
        return name;
      }
    
      @Override
      public List getHierarchy() {
        return hierarchy;
      }
    
      protected void addHierarchy(String name) {
        hierarchy.add(name);
      }
    }
    

    Define Authenticated role (common user role):

    public static class Authenticated extends Anonymous {
      public Authenticated() {
        this(AUTHENTICATED);
      }
    
      protected Authenticated(String name) {
        super(name);
        addHierarchy(AUTHENTICATED);
      }
    }
    

    Define Administrator role (at the top of the evolution):

    public static class Administrator extends Authenticated {
      public Administrator() {
        this(ADMINISTRATOR);
      }
    
      protected Administrator(String name) {
        super(name);
        addHierarchy(ADMINISTRATOR);
      }
    }
    

    Optional - static factory class:

    public static Role getRole(String authState) {
      switch (authState) {
        case ANONYMOUS: return new Anonymous();
        case AUTHENTICATED: return new Authenticated();
        case ADMINISTRATOR: return new Administrator();
        default: throw new IllegalArgumentException("Wrong auth state");
      }
    }
    

    In my CustomUserDetailsService (which implements UserDetailsService) I use role like this:

    private Collection createAuthority(User user) {
      final List authorities = new ArrayList<>();
      AuthStates.Role userAuthState = AuthStates.getRole(user.getAuthState());
      for (String role : userAuthState.getHierarchy()) {
        authorities.add(new SimpleGrantedAuthority(role));
      }
      return authorities;
    }
    

    authorities

    In controllers:

    @PreAuthorize("hasRole('ROLE_AUTHENTICATED')")
    

    Will allow user logged in as ROLE_AUTHENTICATED and ROLE_ADMINISTRATOR both.

提交回复
热议问题