簡體   English   中英

如何為 Spring Security 創建類型安全的用戶角色?

[英]How to create typesafe user roles for Spring Security?

我想將spring-securityROLE_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 {

}

這個問題有點老了,但這是我的看法:

public enum Role implements GrantedAuthority {
    ROLE_USER, ROLE_ADMIN;

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

然后,您可以將它與 @PreAuthorize 和Spring 表達式語言一起使用來授權您的方法和類,如下所示:

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

注意:包名必須是完整的包名 (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 {
}

在此之后,您可以像這樣授權您的方法:

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

部分解決方案:

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

結果是:

@Secured(Role.Code.ADMIN)

您可以使用name()方法而不是value()

如果您的應用中有一個固定的角​​色列表,您還可以在加載用戶時映射到它們,如本答案中所述

如果您使用的是 Lombok,則可以使用@FieldNameConstants注釋:

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

然后像這樣使用它:

@Secured(UserRoles.Fields.ROLE_ADMIN)

也許在未來,會有@EnumNameConstants注釋,它會更適合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM