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

时间:2014-05-13 11:33:03

标签: java spring-security enums

我希望spring-security 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 { } ,这是我无法通过使用枚举类实现的。

我可以在以下代码中更改哪些内容?

{{1}}

4 个答案:

答案 0 :(得分:7)

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

public enum Role implements GrantedAuthority {
    ROLE_USER, ROLE_ADMIN;

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

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

@PreAuthorize("hasRole(T(<package name>.Role).ROLE_ADMIN)")
public void doSomeThing() {
    ...
}

注意:包名必须是整个包名(org.company.project),而不是&lt;和&gt;。

正如您所看到的,根据定义,这不是类型安全的,因为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 {
}

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

@AdminAuthorization
public void doSomething() {
    ...
}

答案 1 :(得分:4)

您可以使用name() method代替value()

如果您的应用中有固定的角色列表,则还可以在加载用户时映射到这些角色,如this answer中所述。

答案 2 :(得分:2)

部分解决方案:

List<WebElement> e=driver.findElements(By.className("GLButton"));
        e.get(≤Position>).click();

结果:

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

答案 3 :(得分:0)

如果您使用的是 Lombok,则可以使用 @FieldNameConstants 注释:

@FieldNameConstants
public class UserRoles {
    private String ROLE_USER, ROLE_ADMIN;
}

然后像这样使用它:

@Secured(UserRoles.Fields.ROLE_ADMIN)

也许将来会有 @EnumNameConstants 注释,它会更适合。