Spring Boot + Auth0에서 간단한 인증 및 권한 부여 (RBAC) 구현

소개



이 게시물에서는 Auth0의 ID Token과 Spring Boot에서 RBAC를 구현하는 방법을 설명합니다.

실현 방법



MP-JWT를 모방하고 ID Token에 권한 정보를 커스텀 클레임으로 부여한다.

Auth0의 ID Token에 권한 정보 부여



Auth0의 ID Token에는 권한 정보가 부여되지 않습니다.
다만, 커스텀 클레임으로 권한 정보를 ID Token 에 부가할 수 있다.

Auth0에 User, Role 및 Permissions 설정



Auth0 문서에 따라 Auth0 사용자에게 권한 정보를 설정합니다.
Access Token은 사용하지 않으므로 Access token에 대한 권한 정보를 허용하는 등의 설정이 필요하지 않습니다.

Auth0의 ID Token에 대한 사용자 지정 클레임 정의



Auth0 대시보드에서 Rules를 열고 ID Token에 대한 사용자 지정 클레임 추가 규칙을 정의합니다.
커스텀 클레임명은 URL 형식의 캐릭터 라인으로 하는 제약이 있다.
이 예에서는 http://example.com/permissions
Rule.js
function (user, context, callback) {
  var map = require('array-map');
  var ManagementClient = require('[email protected]').ManagementClient;
  var management = new ManagementClient({
    token: auth0.accessToken,
    domain: auth0.domain
  });

  var params = { id: user.user_id, page: 0, per_page: 50, include_totals: true };
  management.getUserPermissions(params, function (err, permissions) {
    if (err) {
      // Handle error.
      console.log('err: ', err);
      callback(err);
    } else {
      var permissionsArr = map(permissions.permissions, function (permission) {
        return permission.permission_name;
      });
      context.idToken['http://example.com/permissions'] = permissionsArr;
    }
    callback(null, user, context);
  });
}


ID Token의 권한 정보를 기반으로 Spring Security로 액세스 제어



다음은 사용자 정의 클레임에 추가된 자격 증명을 ID Token에서 가져와 액세스 제어에 사용하는 Spring Boot 앱의 보안 설정 샘플입니다.

Spring Boot 애플리케이션 만들기



Spring Initializr 에서 다음 종속성을 선택하여 프로젝트를 만듭니다.
  • Spring Web
  • OAuth2 Resource Server

    Maven이라면 다음과 같습니다.

  • pom.xml
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
    </dependencies>
    

    JWT 인증 서버 설정



    인증 서버의 설정은 속성만으로 할 수 있습니다.
    Spring Security 로 정의된 이하의 속성을 설정한다.


    속성
    설정값


    spring.security.oauth2.resourceserver.jwt.issuer-uri
    https:// 접두사와 / 접미사가 있는 Auth0 도메인. 말미 /를 생략하면 움직이지 않는다.

    auth0.audience
    Auth0 Application의 클라이언트 ID.



    application.properties
    spring.security.oauth2.resourceserver.jwt.issuer-uri=https://YOUR_DOMAIN/
    auth0.audience=YOUR_APP_CLIENT_ID
    

    맞춤 클레임 획득 설정



    ID Token의 커스텀 클레임에 부가한 권한 정보를 취득해, Security Principal 로 설정한다.

    application.properties
    #Auth0 の Rules で定義したカスタムクレーム名
    permissions.claim=http://example.com/permissions
    

    SecurityConfig.java
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Value(value = "${permissions.claim}")
        private String permissionsClaim;
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
    
            http.authorizeRequests()
                    .mvcMatchers("/api/public").permitAll()
                    .mvcMatchers("/api/private").authenticated()
                    .mvcMatchers("/api/private-scoped").hasAuthority("read:messages")
                    .and().oauth2ResourceServer().jwt()
                    .jwtAuthenticationConverter(jwt -> new JwtAuthenticationToken(jwt,
                            jwt.getClaimAsStringList(permissionsClaim)
                                    .stream()
                                    .map(SimpleGrantedAuthority::new)
                                    .collect(Collectors.toList())));
        }
    }
    

    나중에 Controller를 구현하면 Auth0에서 설정한 권한 정보에 근거해 액세스 제어를 할 수 있다.
    ID Token은 Principal에서 액세스 할 수 있습니다. (구현 클래스는 위의 예와 같이 JwtAuthenticationToken)

    참고



    본 투고에서는 이하의 자료를 참고로 했다.
  • Auth0 핵심 인증 기능 세트 사용 방법 - Auth0 Docs
  • Spring Security 5 Java API: 승인 - Auth0 Docs
  • ID 토큰에 사용자 권한을 추가하려면 어떻게 해야 하나요? - Auth0 커뮤니티
  • OAuth 2.0 / OpenID Connect의 두 가지 토큰 사용 - Qiita
  • MicroProfile JSON 웹 토큰 구성 - IBM Knowledge Center
  • 좋은 웹페이지 즐겨찾기