<Spring Security 권한 부여(Authorization) 흐름도(출처 : 코드스테이츠)>
✋ Authorization관련 안내
위 Spring Security 권한 부여(Authorization) 흐름은 UsernamePasswordAuthenticationFilter를 통해 SecurityContextHolder의 SecurityContext에 저장된 Authentication을 획득하여 Authorization 처리절차를 진행함.
AuthorizationFilter는 SecurityContextHolder로부터 Authentication을 획득
획득한 Authentication과 HttpServletRequest를 AuthorizationManager에게 전달
RequestMatcherDelegatingAuthorizationManager는 RequestMatcher 평가식을 기반으로 평가식에 매치되는 가장 적합한 AuthorizationManager 구현 클래스에게 위임하여 적절한 권한을 가지고 있는지 검증
<AuthorizationManager 구현체 목록(출처 : spring.io)>
@PreAuthorize : 메소드가 호출되기 전에 SpEL 표현식을 사용하여 권한을 검사. 이때, SpEL은 루트 객체를 사용하여 표현식을 평가
@PostAuthorize : 메소드가 호출된 후에 SpEL 표현식을 사용하여 권한을 검사. 이때, SpEL은 루트 객체를 사용하여 표현식을 평가
@PreFilter : 메소드가 호출되기 전에 컬렉션에 대한 필터링을 수행. 이때, SpEL을 사용하여 필터링 조건을 지정할 수 있음.
@PostFilter : 메소드가 호출된 후에 컬렉션에 대한 필터링을 수행. 이때, SpEL을 사용하여 필터링 조건을 지정할 수 있음.
@Secured : 메소드에 대한 보안 권한을 지정. 이때, 권한은 문자열 배열로 지정할 수 있음.
@RolesAllowed : 메소드에 대한 보안 권한을 지정. 이때, 권한은 문자열 배열로 지정할 수 있음.
@Secured vs @RolesAllowed
두 애너테이션 모두 메소드에 대한 보안 권한을 지정하는데 사용하지만, @Secured는 Spring Security에서 지원하는 애너테이션이며, @RolesAllowed는 JSR-250에서 지원하는 애너테이션임. 따라서 @Secured는 Spring Security에서만 사용가능한 애너테이션
표현식 | 설명 |
---|---|
hasRole(String Role) | - 현재 보안 주체(Principal)가 지정된 역할을 가지고 있는지 여부를 확인하고 가지고 있다면 true를 리턴 - hasRole(’admin’)처럼 파라미터로 넘긴 role이 ‘ROLE_’로 시작하지 않으면 기본적으로 추가함(DefaultWebSecurityExpressionHandler의 defaultRolePrefix를 수정하면 커스텀할 수 있다.) |
hasAnyRole(String… roles) | - 현재 보안 주체가 지정한 역할 중 1개라도 가지고 있으면 true를 리턴한다.(문자열 리스트를 콤마로 구분해서 전달한다.)- ex) hasAnyRole(’admin’, ‘user’) |
hasAuthority(String authority) | - 현재 보안 주체가 지정한 권한을 갖고 있는지 여부를 확인하고 가지고 있다면 true를 리턴한다.- ex) hasAuthority(’read’) |
hasAnyAuthority(String… authorities) | - 현재 보안 주체가 지정한 권한 중 하나라도 있으면 true를 리턴한다.- ex) hasAnyAuthority(’read’, ‘write’) |
principal | - 현재 사용자를 나타내는 principal 객체에 직접 접근할 수 있다. |
authentication | - SecurityContext로 조회할 수 있는 현재 Authentication 객체에 직접 접근할 수 있다. |
permitAll | - 항상 true로 평가한다. |
denyAll | - 항상 false로 평가한다. |
isAnonymous() | - 현재 보안 주체가 익명 사용자면 true를 리턴한다. |
isRememberMe() | - 현재 보안 주체가 remember-me 사용자면 true를 리턴한다. |
isAuthenticated() | - 사용자가 익명이 아닌 경우 true를 리턴한다. |
isFullyAuthenticated() | - 사용자가 익명 사용자나 remember-me 사용자가 아니면 true를 리턴한다. |
hasPermission(Object target, Object permission) | - 사용자가 target에 해당 permission 권한이 있으면 true를 리턴한다.ex) hasPermission(domainObject, ‘read’) |
hasPermission(Object targetId, String targetType, Object permission) | - 사용자가 target에 해당 permission 권한이 있으면 true를 리턴한다.ex) hasPermission(1, ‘com.example.domain.Message’, ‘read’) |