[QnA] XSUAA Scope가 Role Collection에 안 묶이는 이유 — 완전 해결 가이드

AI News · 조회 2

[QnA] XSUAA Scope가 Role Collection에 안 묶이는 이유 — 완전 해결 가이드

📖 개요 및 학습 목표

SAP BTP에서 애플리케이션 보안을 설정할 때 가장 흔히 마주치는 문제: "xs-security.json에 scope를 정의했는데 왜 Role Collection에 안 보이지?" 이 글에서는 XSUAA(Authorization and Trust Management Service)의 Scope → Role Template → Role Collection 3단계 구조를 명확히 이해하고, 실제로 발생하는 401/403 에러를 체계적으로 해결하는 방법을 다룹니다.

이 글을 읽으면 다음을 할 수 있습니다:

대상 독자: BTP Cloud Foundry에 앱을 배포한 경험이 있고, 인증/인가 설정에서 막힌 중급 개발자

📚 선수 지식

🔧 환경 / 버전 / 준비물

권장: BTP Trial에서 먼저 테스트한 후 프로덕션에 적용하세요.

이 글에서 다루는 것

💡 핵심 개념

XSUAA의 권한 구조를 도서관 출입 시스템에 비유하면 이해가 쉽습니다:

# XSUAA 권한 흐름 구조
xs-security.json (개발자가 정의)
  └─ scopes: ["Read", "Write", "Admin"]    ← 최소 단위 권한
  └─ role-templates:                         ← Scope 묶음
       ├─ "Viewer"  → [Read]
       └─ "Manager" → [Read, Write, Admin]

BTP Cockpit (관리자가 설정)
  └─ Role Collections:                      ← 사용자에게 할당
       ├─ "AppViewers"  → Viewer Role Template
       └─ "AppManagers" → Manager Role Template
       └─ 사용자 할당: user@company.com → "AppManagers"

흔한 오개념:

💻 실전 코드 — 3단계

1단계: xs-security.json 기본 설정

{
  "xsappname": "my-bookshop-app",
  "tenant-mode": "dedicated",
  "scopes": [
    {
      "name": "$XSAPPNAME.Read",
      "description": "Read books"
    },
    {
      "name": "$XSAPPNAME.Write",
      "description": "Create and update books"
    },
    {
      "name": "$XSAPPNAME.Admin",
      "description": "Full admin access"
    }
  ],
  "role-templates": [
    {
      "name": "Viewer",
      "description": "Read-only access",
      "scope-references": ["$XSAPPNAME.Read"]
    },
    {
      "name": "Manager",
      "description": "Read and write access",
      "scope-references": ["$XSAPPNAME.Read", "$XSAPPNAME.Write"]
    },
    {
      "name": "Administrator",
      "description": "Full access including admin",
      "scope-references": ["$XSAPPNAME.Read", "$XSAPPNAME.Write", "$XSAPPNAME.Admin"]
    }
  ],
  "role-collections": [
    {
      "name": "BookshopViewers",
      "description": "Bookshop read-only users",
      "role-template-references": [
        { "role-template-name": "Viewer", "service-instance-name": "my-bookshop-xsuaa" }
      ]
    },
    {
      "name": "BookshopManagers",
      "description": "Bookshop managers",
      "role-template-references": [
        { "role-template-name": "Manager", "service-instance-name": "my-bookshop-xsuaa" }
      ]
    }
  ]
}

실행: cf create-service xsuaa application my-bookshop-xsuaa -c xs-security.json

결과: BTP Cockpit → Security → Role Collections에서 "BookshopViewers"와 "BookshopManagers"가 생성되었는지 확인합니다.

2단계: CAP 프로젝트에서 역할 기반 접근 제어

// srv/cat-service.cds — @requires로 역할 기반 접근 제어
service CatalogService {
  @requires: 'authenticated-user'
  entity Books as projection on bookshop.Books;

  @requires: 'Manager'
  action submitOrder(book: Books:ID, quantity: Integer) returns { stock: Integer };

  @requires: 'Administrator'
  action deleteAllBooks();
}
// srv/cat-service.js — 핸들러에서 사용자 권한 확인
module.exports = class CatalogService extends cds.ApplicationService {
  async init() {
    this.before('submitOrder', (req) => {
      // req.user.is('Manager')로 역할 확인 가능
      if (!req.user.is('Manager')) {
        req.reject(403, 'Manager 역할이 필요합니다');
      }
      console.log(`주문 요청: user=${req.user.id}, roles=${JSON.stringify(req.user.roles)}`);
    });

    this.on('submitOrder', async (req) => {
      // 비즈니스 로직...
      const { book, quantity } = req.data;
      const db = await cds.connect.to('db');
      const { Books } = db.entities;
      const result = await db.run(
        UPDATE(Books).set({ stock: { '-=': quantity } }).where({ ID: book })
      );
      return { stock: result };
    });

    await super.init();
  }
};

3단계: CLI로 Role Collection 검증 및 사용자 할당

-- CF CLI로 XSUAA 인스턴스 확인
$ cf services | grep xsuaa
my-bookshop-xsuaa   xsuaa   application   create succeeded

-- Service Key 생성하여 XSUAA 설정 확인
$ cf create-service-key my-bookshop-xsuaa my-key
$ cf service-key my-bookshop-xsuaa my-key
-- 출력에서 clientid, clientsecret, url 확인

-- 토큰 발급 테스트 (Client Credentials)
$ curl -X POST "{xsuaa-url}/oauth/token"   -H "Content-Type: application/x-www-form-urlencoded"   -d "grant_type=client_credentials&client_id={clientid}&client_secret={clientsecret}"
-- 응답의 scope 필드에서 할당된 scope 목록 확인

-- Role Collection에 사용자 할당 (BTP Cockpit 또는 CLI)
$ cf curl "/sap/rest/authorization/v2/rolecollections/BookshopManagers/users"   -X PUT -d '{"username":"user@company.com","origin":"sap.default"}'

⚠️ 흔한 실수 / 트러블슈팅

Q1: xs-security.json을 수정했는데 변경사항이 반영 안 돼요

Q2: 403 Forbidden — "Insufficient scope"

Q3: 멀티테넌트 환경에서 "token audience invalid"

Q4: Role Collection이 BTP Cockpit에 안 보여요

🚀 다음 단계 / 관련 주제

자세한 내용은 본문에서

📚 참고 자료


📌 본 게시물은 AI(Claude)가 공개된 자료를 기반으로 자동 생성한 콘텐츠입니다. 기술 내용의 정확성은 SAP 공식 문서 와 교차 확인하시기 바랍니다.

™ SAP, S/4HANA, ABAP, Fiori, SAP BTP 등은 SAP SE 또는 그 계열사의 등록 상표입니다. 본 사이트는 SAP SE 와 공식적인 관련이 없는 비공식 학습 자료 입니다.

📧 저작권 침해 / 오류 / 콘텐츠 신고: btpstacks.com 의 "문의" 메뉴를 이용해주세요.