'enum'에 해당되는 글 1건

  1. [spring security] enum으로 @Secured 권한 관리하기

[spring security] enum으로 @Secured 권한 관리하기

Spring Security Annotations


spring security는 @Secured나 @PreAuthorize 같은 어노테이션을 사용하여 메소드에 권한을 줄 수 있다. Secured 어노테이션은 @Secured("ROLE_USER") 와 같이 권한 이름을 파라미터로 사용하는데, 이 권한 이름들을 Enum에 정의하고, 사용해보자.

아래와 같은 권한용 Enum이 있다.

import org.springframework.security.core.GrantedAuthority;

public enum MyAuthority implements GrantedAuthority{

    USER("ROLE_USER", "유저권한"),
    ADMIN("ROLE_ADMIN", "어드민권한");

    private String authority;
    private String description;

    private MyAuthority(String authority, String description){
        this.authority = authority;
        this.description = description;
    }

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

    public String getDescription() {
        return description;
    }

}

그리고 나서 @Secured에서 아래와 같이 사용해보자.

@Secured(MyAuthority.USER.getAuthority())

@Secured안에는 String이 들어가고, getAuthority()는 String을 리턴하는데, "The value for annotation attribute Secured.value must be a constant expression" 라는 컴파일 에러가 났다. 어노테이션안에 Enum을 사용한 적은 많은 것 같은데, 왜 에러일까?

Enum 타입 사용이 가능했던 어노테이션들은 실제로 Enum을 받도록 만들어진 어노테이션이였다. @RequestMapping의 method를 예로들면, 타입이 String이 아닌 RequestMethod 라는 Enum을 받도록 되어있다. 만약 @Secured에서 Enum을 사용하려 했다면, String이 아닌 Enum을 받도록 설계되어 있어야 한다.

그렇다면 방법은 전혀 없는 것일까? 차선책으로는 static 레벨에 final로 권한을 선언하는 것이다. Enum 안에 ROLE_USER와 같은 권한들은 객체안에 생성되서 컴파일러가 가변적이라고 판단하는 것 같다. 그래서 코드를 아래와 같이 바꾸었다.

import org.springframework.security.core.GrantedAuthority;

public enum MyAuthority implements GrantedAuthority{

    USER(ROLES.USER, "유저권한"),
    ADMIN(ROLES.ADMIN, "어드민권한");

    public static class ROLES{
        public static final String USER = "ROLE_USER";
        public static final String ADMIN = "ROLE_ADMIN";
    }

    private String authority;
    private String description;

    private MyAuthority(String authority, String description){
        this.authority = authority;
        this.description = description;
    }

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

    public String getDescription() {
        return description;
    }
}

@Secured를 사용하는 부분은 아래와 같이 바꾸면 잘 된다.

@Secured(MyAuthority.ROLES.USER)

기존의 목표였던 권한을 Enum에서 관리하면서, Secured 어노테이션에서도 그 권한을 참조 할 수 있게 되었다. String을 파라미터로 받는 어노테이션에 변수를 전달하고 싶을 때는 final로 선언되어 있어야 한다.