如何为Spring Security创建类型安全的用户角色?

mem*_*und 11 java enums spring-security

我想利用spring-securitywith ROLE_ADMINROLE_USER角色.

因此,我尝试创建一个类型安全的枚举类,但是@Secured注释需要一个常量String,这是我无法通过使用枚举类实现的.

我可以在以下代码中更改什么?

public enum UserRole {
    ADMIN("ROLE_ADMIN");

    private String role;

    public UserRole(String role) {  
        this.role = role;
    }
}

//error: The value for annotation attribute Secured.value must be a constant expression
@Secured(USerRole.ADMIN.value())
public class SecuredView {

}
Run Code Online (Sandbox Code Playgroud)

Ter*_*ran 12

部分解决方案:

public enum Role implements GrantedAuthority {

    ADMIN(Code.ADMIN),
    USER(Code.USER);

    private final String authority;

    Role(String authority) {
        this.authority = authority;
    }

    @Override
    public String getAuthority() {
        return authority;
    }

    public class Code {
        public static final String ADMIN = "ROLE_ADMIN";
        public static final String USER = "ROLE_USER";
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

@Secured(Role.Code.ADMIN)
Run Code Online (Sandbox Code Playgroud)


小智 8

这个问题有点旧,但这是我的看法:

public enum Role implements GrantedAuthority {
    ROLE_USER, ROLE_ADMIN;

    @Override
    public String getAuthority() {
        return name();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将它与@PreAuthorize和Spring Expression Language一起使用来授权您的方法和类,如下所示:

@PreAuthorize("hasRole(T(<package name>.Role).ROLE_ADMIN)")
public void doSomeThing() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

注意:包名称必须是整个包名称(org.company.project),而不包含<和>.

正如您所看到的,每个定义都不是类型安全的,因为SpEL表达式仍然是字符串,但像IntelliJ这样的IDE会识别它们,并会告诉您任何错误.

您可以使用hasAnyRole()将@PreAuthorize与多个角色一起使用.

当然,对于许多角色来说,这可能会变得有点冗长,但你可以通过创建自己的注释来使它变得更漂亮:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@PreAuthorize("hasRole(T(<package name>.Role).ROLE_ADMIN)")
public @interface AdminAuthorization {
}
Run Code Online (Sandbox Code Playgroud)

在此之后,您可以像这样授权您的方法:

@AdminAuthorization
public void doSomething() {
    ...
}
Run Code Online (Sandbox Code Playgroud)