Spring Security (Authorization)

zirung-i·2024년 2월 28일

Spring Security

목록 보기
2/2
post-thumbnail

Authorization Architecture

Authorities

GrantedAuthority 객체는 AuthenticationManager에 의해 인증 개체에 Authentication 객체에 삽입되고 나중에 권한 부여 결정을 내릴 때 AccessDecisionManager 인스턴스에서 읽혀진다.

GrantedAuthority 인터페이스는 하나의 메서드만을 갖는다.

String getAuthority();

위 메서드는 AuthorizationManager 인스턴스에서 GrantedAuthority의 정확한 String 표현을 얻는 데 사용된다. String으로 반환하면 대부분의 AuthorizationManager 구현체에서 GrantAuthority를 쉽게 읽을 수 있다. 만약 String으로 정확하게 표현할 수 없는 경우 getAuthority() 메서드는 null을 반환해야 한다.

기본적으로 role-based 권한 부여 규칙에는 ROLE_이 접두사로 포함된다. 이는 "USER" 권한을 요청하는 security context가 있을 경우 기본적으로 "ROLE_USER"를 반환하는 GrantedAuthority#getAuthority를 찾아서 사용한다는 것을 의미한다.

만약 앞에 붙는 ROLE_을 커스텀하게 변경하고 싶다면 GrantedAuthorityDefaults를 사용하면 된다.

@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
	return new GrantedAuthorityDefaults("MYPREFIX_");
}

Spring Security의 설정 파일은 @Configuration 어노테이션으로 인해 Spring Bean으로 관리된다. Spring이 클래스를 초기화하고 관리하기 전에 GrantedAuthorityDefaults가 먼저 존재해야 하기 때문에 static 메서드를 사용한다.





Invocation Handling

Spring Security는 메서드 호출이나 웹 요청과 같은 객체에 대한 접근을 제어하는 인터셉터를 제공한다. 객체에 접근이 허용되는지, 값 반환이 허용되는지 여부는 AuthorizationManager 인스턴스에 의해 이루어진다.

The AuthorizationManager

AuthorizationManagerAccessDecisionManagerAccessDecisionVoter를 대체하기 때문에 이 두 인터페이스는 AuthorizationManager로 변경하는 편이 좋다.

AuthorizationManager는 Spring Security의 request-based, method-based, message-based 인증 요소들에 의해 호출되며 접근 결정을 내리는 역할을 한다. 이 인터페이스는 두 가지 메서드를 포함한다.

AuthorizationDecision check(Supplier<Authentication> authentication, Object secureObject);

default AuthorizationDecision verify(Supplier<Authentication> authentication, Object secureObject)
        throws AccessDeniedException {
    // ...
}

위의 check() 메서드에는 인증에 대한 결정을 내리는데 필요한 모든 정보가 전달된다. 특히 보안 Object는 실제 보안 객체 호출에 포함된 argument를 검사할 수 있다. 구현체에서는 접근이 허용된 경우 긍정적인 AuthorizationDecision을 반환하고 접근이 거부된 경우 부정적인 AuthorizationDecision을 반환하며 결정을 내리지 않는 경우 null을 반환할 것이다.
호출을 확인하고 부정적인 AuthorizationDecision인 경우 AccessDeniedException을 반환한다.

Delegate-based AuthorizationManager Implementations

사용자는 인증의 모든 측면을 제어하기 위한 자신만의 AuthorizationManager를 작성할 수 있다.
또한 Spring Security는 기본 AuthorizationManager와 협력하여 동작하는 AuthorizationManager를 작성할 수 있게 제공한다.

RequestMatcherDelegatingAuthorizationManager는 요청을 적절한 위임 AuthorizationManager와 일치시킨다. 메서드 보안을 위해 AuthorizationManagerBeforeMethodInterceptorAuthorizationManagerAfterMethodInterceptor를 사용할 수 있다.

AuthorityAuthorizationManager

가장 일반적인 위임 AuthorizationManager이다.
인증에 구성된 권한이 포함되어 있으면 긍정적인 AuthorizationDecision을 반환한다. 그렇지 않으면 부정적인 AuthorizationDecision을 반환한다.

AuthenticatedAuthorizationManager

익명 사용자, 완전히 인증된 사용자, remember-me로 인증한 사용자를 구별할 수 있다.
많은 사이트에서 Remember-Me 인증을 한 사용자에게 특정 리소스에 대해서 접근을 허용하지만 전체 엑세스를 위해서는 로그인하도록 한다.

AuthorizationManagers

AuthorizationManager들 중에는 AuthorizationManager를 보다 정교한 표현식으로 구성하는 데 도움을 주는 정적 팩토리도 있다.

Custom Authorization Managers

사용자가 정의한 AuthorizationManager를 구현할 수 도 있으며 원하는 접근 제어 논리를 추가할 수 있다.





Adapting AccessDecisionManager and AccessDecisionVoters

AuthorizationManager 이전에는 AccessDecisionManagerAccessDecisionVoter를 사용했다.

Hierarchical Roles

애플리케이션의 어떠한 Role이 다른 Role을 '포함' 해야 하는 것은 일반적인 요구 사항이다. 예를 들면 '관리자는 일반 사용자가 할 수 있는 모든 작업을 수행할 수 있게 해야한다.' 라는 요구사항이 있다면 관리자는 사용자의 Role도 가져야 한다.

Role Hierarchy를 사용하면 어떤 Role(혹은 권한)이 다른 Role을 포함하도록 구성할 수 있다.
RoleHierarchyVoterRoleHierarchy로 구성되어 Role의 계층구조를 지정할 수 있다.

@Bean
static RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF\n" +
            "ROLE_STAFF > ROLE_USER\n" +
            "ROLE_USER > ROLE_GUEST");
    return hierarchy;
}

// 메서드 기반 인증을 적용하고 싶으면 다음 메서드도 작성
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
	DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
	expressionHandler.setRoleHierarchy(roleHierarchy);
	return expressionHandler;
}

위 코드에서 권한의 계층 구조는 다음과 같다.
ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST
여기에서 > 기호는 포함을 의미한다고 생각하면 된다.


Authorize HttpServletRequests

추후 작성 예정

profile
지렁지렁

0개의 댓글