我希望spring-security
ROLE_ADMIN
和ROLE_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}}
答案 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 注释,它会更适合。