애플리케이션 및 서비스 보안 가이드
Red Hat Single Sign-On 7.6과 함께 사용하는 경우
초록
보다 포괄적 수용을 위한 오픈 소스 용어 교체
Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 용어를 교체하기 위해 최선을 다하고 있습니다. 먼저 마스터(master), 슬레이브(slave), 블랙리스트(blacklist), 화이트리스트(whitelist) 등 네 가지 용어를 교체하고 있습니다. 이러한 변경 작업은 작업 범위가 크므로 향후 여러 릴리스에 걸쳐 점차 구현할 예정입니다. 자세한 내용은 CTO Chris Wright의 메시지를 참조하십시오.
1장. 애플리케이션 및 서비스 보안 계획
Red Hat Single Sign-On은 OpenID Connect( OAuth 2.0의 확장) 및 SAML 2.0을 모두 지원합니다. 고객과 서비스를 보호 할 때 가장 먼저 결정해야하는 것은 어느 것을 사용할 것인지 결정하는 것입니다. 또한 OpenID Connect 및 SAML을 사용하여 일부 사용자를 보호하도록 선택할 수도 있습니다.
클라이언트 및 서비스를 보호하려면 선택한 프로토콜의 어댑터 또는 라이브러리도 필요합니다. Red Hat Single Sign-On에는 선택한 플랫폼에 대한 자체 어댑터가 제공되지만 일반 OpenID Connect Relying Party 및 SAML Service Provider 라이브러리를 사용할 수도 있습니다.
1.1. 클라이언트 어댑터
Red Hat Single Sign-On 클라이언트 어댑터는 Red Hat Single Sign-On을 통해 애플리케이션 및 서비스를 매우 쉽게 보호할 수 있는 라이브러리입니다. 기본 플랫폼 및 프레임워크에 긴밀하게 통합되어 있기 때문에 라이브러리가 아닌 어댑터를 호출합니다. 이렇게 하면 어댑터를 쉽게 사용할 수 있으며 라이브러리에서 일반적으로 필요한 것보다 상용구 코드가 덜 필요합니다.
1.2. 지원되는 플랫폼
Red Hat Single Sign-On을 사용하면 OpenID Connect 및 SAML 프로토콜을 사용하여 다양한 플랫폼에서 실행되는 애플리케이션을 보호할 수 있습니다.
1.2.1. OpenID Connect
1.2.1.1. Java
1.2.1.2. JavaScript (client-side)
1.2.1.3. Node.js (server-side)
1.2.2. SAML
1.2.2.1. Java
1.2.2.2. Apache HTTP Server
1.3. 지원되는 프로토콜
Red Hat Single Sign-On은 OpenID Connect 및 SAML 프로토콜을 모두 지원합니다.
1.3.1. OpenID Connect
OIDC( OpenID Connect )는 OAuth 2.0 의 확장인 인증 프로토콜입니다. OAuth 2.0은 권한 부여 프로토콜 구축을 위한 프레임워크일 뿐이며 주로 불완전하지만 OIDC는 완전한 인증 및 권한 부여 프로토콜입니다. OIDC는 또한 Json Web Token (JWT) 표준을 많이 사용합니다. 이러한 표준은 아이덴티티 토큰 JSON 형식 및 데이터를 컴팩트하고 웹 친화적인 방법으로 디지털 서명하고 암호화하는 방법을 정의합니다.
OIDC를 사용할 때 실제로 두 가지 유형의 사용 사례가 있습니다. 첫 번째는 Red Hat Single Sign-On 서버에 사용자를 인증하도록 요청하는 애플리케이션입니다. 로그인에 성공하면 애플리케이션은 ID 토큰과 액세스 토큰 을 수신합니다. ID 토큰 에는 사용자 이름, 이메일 및 기타 프로필 정보와 같은 사용자에 대한 정보가 포함되어 있습니다. 액세스 토큰은 영역에 의해 디지털 서명되며 애플리케이션에서 애플리케이션에 액세스할 수 있는 리소스를 결정하는 데 사용할 수 있는 액세스 정보(예: 사용자 역할 매핑)를 포함합니다.
두 번째 유형의 사용 사례는 원격 서비스에 액세스하려는 클라이언트의 경우입니다. 이 경우 클라이언트는 사용자를 대신하여 다른 원격 서비스에서 호출하는 데 사용할 수 있는 액세스 토큰 을 Red Hat Single Sign-On에 요청합니다. Red Hat Single Sign-On은 사용자를 인증한 다음 사용자에게 요청하는 클라이언트에 대한 액세스 권한을 부여하는 데 동의하도록 요청합니다. 그러면 클라이언트에서 액세스 토큰 을 받습니다. 이 액세스 토큰은 영역에 의해 디지털 서명됩니다. 클라이언트는 이 액세스 토큰 을 사용하여 원격 서비스에서 REST 호출을 수행할 수 있습니다. REST 서비스는 액세스 토큰 을 추출하고 토큰 서명을 확인한 다음, 요청을 처리할지 여부를 토큰 내 액세스 정보에 따라 결정합니다.
1.3.2. SAML 2.0
SAML 2.0 은 OIDC와 유사한 사양이지만 훨씬 오래되고 성숙해졌습니다. 이 루트는 CHAP에 루트와 WS-* 사양의 plethora * 사양을 가지고 있으므로 OIDC보다 조금 더 자세한 경향이 있습니다. SAML 2.0은 주로 인증 서버와 애플리케이션 간에 XML 문서를 교환하여 작동하는 인증 프로토콜입니다. XML 서명 및 암호화는 요청 및 응답을 확인하는 데 사용됩니다.
Red Hat Single Sign-On SAML에서는 브라우저 애플리케이션과 REST 호출이라는 두 가지 유형의 사용 사례를 제공합니다.
SAML을 사용할 때 실제로 두 가지 유형의 사용 사례가 있습니다. 첫 번째는 Red Hat Single Sign-On 서버에 사용자를 인증하도록 요청하는 애플리케이션입니다. 로그인에 성공하면 애플리케이션에 사용자에 대한 다양한 속성을 지정하는 SAML 어설션이라는 내용이 포함된 XML 문서가 수신됩니다. 이 XML 문서는 영역에 의해 디지털 서명되며 애플리케이션에서 애플리케이션에서 액세스할 수 있는 리소스를 결정하는 데 사용할 수 있는 액세스 정보(예: 사용자 역할 매핑)를 포함합니다.
두 번째 유형의 사용 사례는 원격 서비스에 액세스하려는 클라이언트의 경우입니다. 이 경우 클라이언트는 사용자를 대신하여 다른 원격 서비스에서 호출할 수 있는 SAML 어설션을 Red Hat Single Sign-On에 요청합니다.
1.3.3. OpenID Connect vs. SAML
OpenID Connect와 SAML 중에서 선택하는 것은 더 성숙한 프로토콜(SAML) 대신 최신 프로토콜(OIDC)을 사용하는 데 그치지 않습니다.
대부분의 경우 Red Hat Single Sign-On에서 OIDC 사용을 권장합니다.
SAML은 OIDC보다 조금 더 자세한 경향이 있습니다.
교환된 데이터의 세부 정보 표시 외에도 OIDC가 웹과 작동하도록 설계된 사양을 비교하면 SAML이 웹에서 작동하도록 다시 조정되었습니다. 예를 들어 OIDC는 SAML보다 클라이언트 측에서 보다 쉽게 구현할 수 있으므로 HTML5/JavaScript 애플리케이션에도 적합합니다. 토큰은 JSON 형식이므로 JavaScript에서 더 쉽게 사용할 수 있습니다. 또한 웹 애플리케이션에서 보안을 보다 쉽게 구현할 수 있는 몇 가지 유용한 기능을 찾을 수 있습니다. 예를 들어, 사용자가 아직 로그인했는지 여부를 확인하기 위해 사양에서 사용하는 iframe 동작을 확인하십시오.
그러나 SAML은 그 용도를 가지고 있습니다. OIDC 사양이 진화하면서 SAML이 수년 동안 보유하고 있는 기능을 더 많이 구현할 수 있다는 것을 알 수 있습니다. OIDC를 통해 SAML을 선택하는 이유는 OIDC를 통해 SAML을 선택하는 경우가 많으며, 이는 이미 보안된 기존 애플리케이션이 있기 때문입니다.
1.4. 용어
이 용어는 이 가이드에서 사용됩니다.
-
클라이언트는
Red Hat Single Sign-On과 상호 작용하여 사용자를 인증하고 토큰을 얻는 엔티티입니다. 대부분의 경우 클라이언트는 사용자에게 SSO(Single Sign-On) 환경을 제공하고 서버에서 발행한 토큰을 사용하여 다른 서비스에 액세스하는 사용자를 대신하여 작동하는 애플리케이션 및 서비스입니다. 또한 클라이언트는 토큰을 취득하고 다른 서비스에 액세스하기 위해 자체적으로 작동하는 데에만 관심이 있는 엔티티일 수 있습니다. -
애플리케이션에는 각 프로토콜의 특정 플랫폼에서 작동하는 다양한 애플리케이션이 포함되어 있습니다.
-
클라이언트 어댑터
는 Red Hat Single Sign-On을 사용하여 애플리케이션 및 서비스를 쉽게 보호할 수 있는 라이브러리입니다. 기본 플랫폼 및 프레임워크에 긴밀하게 통합할 수 있습니다. -
클라이언트를 생성하고
것은 동일한 작업입니다.클라이언트를
등록하는클라이언트 생성
은 관리 콘솔을 사용하여 클라이언트를 생성하는 데 사용되는 용어입니다.클라이언트 등록은
Red Hat Single Sign-On 클라이언트 등록 서비스를 사용하여 클라이언트를 등록하는 데 사용되는 용어입니다. -
서비스 계정은
자체적으로 토큰을 가져올 수 있는 클라이언트 유형입니다.
1.5. 애플리케이션 및 서비스 보안을 위한 기본 단계
다음은 Red Hat Single Sign-On에서 애플리케이션 또는 서비스를 보호하는 기본 단계입니다.
다음 옵션 중 하나를 사용하여 클라이언트를 구성합니다.
- Red Hat Single Sign-On 어댑터
- 일반 OpenID 연결 또는 SAML 라이브러리
다음 옵션 중 하나를 사용하여 클라이언트를 등록합니다.
- Red Hat Single Sign-On 관리 콘솔
- 고객 등록 서비스
- CLI
2장. OpenID Connect를 사용하여 애플리케이션 및 서비스 보안
이 섹션에서는 Red Hat Single Sign-On 어댑터 또는 일반 OpenID Connect Relying Party 라이브러리를 사용하여 OpenID Connect에서 애플리케이션 및 서비스를 보호하는 방법에 대해 설명합니다.
2.1. Java 어댑터
Red Hat Single Sign-On에는 다양한 Java 어댑터가 포함되어 있습니다. 올바른 어댑터를 선택하는 것은 대상 플랫폼에 따라 다릅니다.
모든 Java 어댑터는 Java Adapters Config 장에 설명된 일반적인 구성 옵션 세트를 공유합니다.
2.1.1. Java 어댑터 구성
Red Hat Single Sign-On에서 지원하는 각 Java 어댑터는 간단한 JSON 파일로 구성할 수 있습니다. 다음과 같이 표시됩니다.
{ "realm" : "demo", "resource" : "customer-portal", "realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB", "auth-server-url" : "https://localhost:8443/auth", "ssl-required" : "external", "use-resource-role-mappings" : false, "enable-cors" : true, "cors-max-age" : 1000, "cors-allowed-methods" : "POST, PUT, DELETE, GET", "cors-exposed-headers" : "WWW-Authenticate, My-custom-exposed-Header", "bearer-only" : false, "enable-basic-auth" : false, "expose-token" : true, "verify-token-audience" : true, "credentials" : { "secret" : "234234-234234-234234" }, "connection-pool-size" : 20, "socket-timeout-millis" : 5000, "connection-timeout-millis" : 6000, "connection-ttl-millis" : 500, "disable-trust-manager" : false, "allow-any-hostname" : false, "truststore" : "path/to/truststore.jks", "truststore-password" : "geheim", "client-keystore" : "path/to/client-keystore.jks", "client-keystore-password" : "geheim", "client-key-password" : "geheim", "token-minimum-time-to-live" : 10, "min-time-between-jwks-requests" : 10, "public-key-cache-ttl" : 86400, "redirect-rewrite-rules" : { "^/wsmaster/api/(.*)$" : "/api/$1" } }
{
"realm" : "demo",
"resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
"auth-server-url" : "https://localhost:8443/auth",
"ssl-required" : "external",
"use-resource-role-mappings" : false,
"enable-cors" : true,
"cors-max-age" : 1000,
"cors-allowed-methods" : "POST, PUT, DELETE, GET",
"cors-exposed-headers" : "WWW-Authenticate, My-custom-exposed-Header",
"bearer-only" : false,
"enable-basic-auth" : false,
"expose-token" : true,
"verify-token-audience" : true,
"credentials" : {
"secret" : "234234-234234-234234"
},
"connection-pool-size" : 20,
"socket-timeout-millis" : 5000,
"connection-timeout-millis" : 6000,
"connection-ttl-millis" : 500,
"disable-trust-manager" : false,
"allow-any-hostname" : false,
"truststore" : "path/to/truststore.jks",
"truststore-password" : "geheim",
"client-keystore" : "path/to/client-keystore.jks",
"client-keystore-password" : "geheim",
"client-key-password" : "geheim",
"token-minimum-time-to-live" : 10,
"min-time-between-jwks-requests" : 10,
"public-key-cache-ttl" : 86400,
"redirect-rewrite-rules" : {
"^/wsmaster/api/(.*)$" : "/api/$1"
}
}
${…} 시스템 속성 교체를 위해 ${…}
를 사용할 수 있습니다. 예를 들어 ${jboss.server.config.dir}
은 /path/to/Red Hat Single Sign-On
으로 교체됩니다. env
접두사를 통해 환경 변수 교체도 지원됩니다(예: ${env.MY_ENVIRONMENT_VARIABLE}
).
초기 구성 파일은 관리자 콘솔에서 가져올 수 있습니다. 이 작업은 관리자 콘솔을 열고 메뉴에서 Clients
를 선택하고 해당 클라이언트를 클릭하여 수행할 수 있습니다. 클라이언트 페이지가 열리면 설치
탭을 클릭하고 Keycloak OIDC JSON
을 선택합니다.
다음은 각 구성 옵션에 대한 설명입니다.
- 영역
- 영역의 이름입니다. 이것은 필수입니다.
- resource
- 애플리케이션의 클라이언트 ID입니다. 각 애플리케이션에는 애플리케이션을 식별하는 데 사용되는 클라이언트 ID가 있습니다. 이것은 필수입니다.
- realm-public-key
- 영역 공개 키의 PEM 형식. 관리 콘솔에서 이 값을 가져올 수 있습니다. 이 값은 OPTIONAL이며 설정하지 않는 것이 좋습니다. 설정되지 않은 경우 어댑터는 Red Hat Single Sign-On에서 이 값을 다운로드하고 필요한 경우 항상 다시 다운로드합니다(예: Red Hat Single Sign-On이 키를 회전). 그러나 realm-public-key가 설정되어 있으면 어댑터는 Red Hat Single Sign-On에서 새 키를 다운로드하지 않으므로 Red Hat Single Sign-On이 키를 회전하면 어댑터가 중단됩니다.
- auth-server-url
-
Red Hat Single Sign-On 서버의 기본 URL입니다. 다른 모든 Red Hat Single Sign-On 페이지 및 REST 서비스 엔드포인트는 여기에서 파생됩니다. 일반적으로
https://host:port/auth
형식입니다. 이것은 필수입니다. - SSL-필수
-
Red Hat Single Sign-On 서버와의 모든 통신이 HTTPS를 통해 이루어집니다. 프로덕션 환경에서 이 값은
모두
로 설정되어야 합니다. 이것은 선택 사항입니다. 기본값은 외부 이므로 기본적으로 외부 요청에 HTTPS가 필요합니다. 유효한 값은 'all', 'external' 및 'none'입니다. - confidential-port
- SSL/TLS를 통한 보안 연결에 Red Hat Single Sign-On 서버에서 사용하는 기밀 포트입니다. 이것은 선택 사항입니다. 기본값은 8443 입니다.
- use-resource-role-mappings
- true로 설정하면 어댑터는 사용자의 애플리케이션 수준 역할 매핑을 위해 토큰 내부를 찾습니다. false인 경우 사용자 역할 매핑의 영역 수준을 확인합니다. 이것은 선택 사항입니다. 기본값은 false입니다.
- public-client
- true로 설정하면 어댑터에서 클라이언트의 인증 정보를 Red Hat Single Sign-On으로 보내지 않습니다. 이것은 선택 사항입니다. 기본값은 false입니다.
- enable-cors
- 이를 통해 CORS 지원이 가능합니다. CORS 사전 진행 요청을 처리합니다. 또한 액세스 토큰을 확인하여 유효한 출처를 결정합니다. 이것은 선택 사항입니다. 기본값은 false입니다.
- cors-max-age
-
CORS가 활성화된 경우
Access-Control-Max-Age
헤더의 값을 설정합니다. 이것은 선택 사항입니다. 설정하지 않으면 이 헤더가 CORS 응답에서 반환되지 않습니다. - cors-allowed-methods
-
CORS가 활성화된 경우
Access-Control-Allow-Methods
헤더의 값을 설정합니다. 쉼표로 구분된 문자열이어야 합니다. 이것은 선택 사항입니다. 설정하지 않으면 이 헤더가 CORS 응답에서 반환되지 않습니다. - cors-allowed-headers
-
CORS를 활성화하면
Access-Control-Allow-Headers
헤더의 값을 설정합니다. 쉼표로 구분된 문자열이어야 합니다. 이것은 선택 사항입니다. 설정하지 않으면 이 헤더가 CORS 응답에서 반환되지 않습니다. - cors-exposed-headers
-
CORS를 활성화하면
Access-Control-Expose-Headers
헤더의 값을 설정합니다. 쉼표로 구분된 문자열이어야 합니다. 이것은 선택 사항입니다. 설정하지 않으면 이 헤더가 CORS 응답에서 반환되지 않습니다. - bearer-only
- 서비스의 경우 true 로 설정해야 합니다. 활성화된 경우 어댑터는 사용자 인증을 시도하지 않고 전달자 토큰만 확인합니다. 이것은 선택 사항입니다. 기본값은 false입니다.
- autodetect-bearer-only
-
애플리케이션이 웹 애플리케이션 및 웹 서비스(예: CloudEvent 또는 REST)를 모두 제공하는 경우 true 로 설정해야 합니다. 이를 통해 인증되지 않은 웹 애플리케이션의 사용자를 Red Hat Single Sign-On 로그인 페이지로 리디렉션할 수 있지만 로그인 페이지로 리디렉션하지 않기 때문에 인증되지 않은 iPXE 또는 REST 클라이언트로 HTTP
401
상태 코드를 보낼 수 있습니다. Red Hat Single Sign-On은X-Requested-With
,ECDHEAction
또는Accept
와 같은 일반적인 헤더를 기반으로 합니다. 기본값은 false입니다. - enable-basic-auth
- 어댑터가 기본 인증도 지원합니다. 이 옵션을 활성화하면 시크릿 도 제공해야 합니다. 이것은 선택 사항입니다. 기본값은 false입니다.
- expose-token
-
true
인 경우 인증된 브라우저 클라이언트(JavaScript HTTP 호출을 통해)는 URLroot/k_query_bearer_token
을 통해 서명된 액세스 토큰을 가져올 수 있습니다. 이것은 선택 사항입니다. 기본값은 false입니다. - 인증 정보
- 애플리케이션의 자격 증명을 지정합니다. 키가 인증 정보 유형이고 값은 인증 정보 유형의 값인 오브젝트 표기법입니다. 현재 암호 및 jwt가 지원됩니다. 이는 '기밀' 액세스 유형이 있는 클라이언트의 경우에만 필수 사항입니다.
- connection-pool-size
-
이 구성 옵션은 풀링해야 하는 Red Hat Single Sign-On 서버에 대한 연결 수를 정의합니다. 이것은 선택 사항입니다. 기본값은
20
입니다. - socket-timeout-millis
-
연결을 밀리초 단위로 설정한 후 데이터를 기다리는 소켓의 시간 초과입니다. 두 데이터 패킷 사이에 비활성의 최대 시간. 시간 제한 값이 0은 무한 타임아웃으로 해석됩니다. 음수 값은 정의되지 않은 것으로 해석됩니다(해당되는 경우 시스템 기본값). 기본값은
-1
입니다. 이것은 선택 사항입니다. - connection-timeout-millis
-
원격 호스트와의 연결을 밀리초 단위로 설정하기 위한 시간 초과입니다. 시간 제한 값이 0은 무한 타임아웃으로 해석됩니다. 음수 값은 정의되지 않은 것으로 해석됩니다(해당되는 경우 시스템 기본값). 기본값은
-1
입니다. 이것은 선택 사항입니다. - connection-ttl-millis
-
클라이언트의 연결 시간(밀리초)입니다. 값이 0 보다 작거나 같은 값은 무한 값으로 해석됩니다.A value less than or equal to zero is interpreted as an infinite value. 기본값은
-1
입니다. 이것은 선택 사항입니다. - disable-trust-manager
-
Red Hat Single Sign-On 서버에 HTTPS가 필요하며 이 구성 옵션이
true
로 설정된 경우 truststore를 지정할 필요가 없습니다. 이 설정은 개발 중에만 사용해야 하며, SSL 인증서 확인을 비활성화하므로 프로덕션에서는 사용하지 않아야 합니다. 이것은 선택 사항입니다. 기본값은false
입니다. - allow-any-hostname
-
Red Hat Single Sign-On 서버에 HTTPS가 필요하며 이 구성 옵션이
true
로 설정되어 있으면 신뢰 저장소를 통해 Red Hat Single Sign-On 서버의 인증서의 유효성을 검사하지만 호스트 이름 검증은 수행되지 않습니다. 이 설정은 개발 중에만 사용해야 하며, SSL 인증서 확인을 비활성화하므로 프로덕션에서는 사용하지 않아야 합니다. 이 설정은 테스트 환경에서 유용할 수 있습니다. 이 옵션은 선택 사항입니다. 기본값은false
입니다. - proxy-url
- HTTP 프록시가 사용되는 경우의 URL입니다.
- truststore
-
값은 신뢰 저장소 파일의 파일 경로입니다. 경로 접두사를
classpath:
인 경우 대신 배포의 classpath에서 truststore를 가져옵니다. Red Hat Single Sign-On 서버로의 발신 HTTPS 통신에 사용됩니다. HTTPS 요청을 수행하는 클라이언트는 통신 중인 서버의 호스트를 확인할 방법이 필요합니다. 이것이 신뢰가 하는 것입니다. 키 저장소에는 하나 이상의 신뢰할 수 있는 호스트 인증서 또는 인증 기관이 포함됩니다. Red Hat Single Sign-On 서버의 SSL 키 저장소의 공개 인증서를 추출하여 이 신뢰 저장소를 생성할 수 있습니다.ssl-required
가none
또는disable-trust-manager
가true
인 경우가 아니면 REQUIRED 입니다. - truststore-password
-
신뢰 저장소의 암호입니다. truststore가 설정되어 있고
truststore
에 암호가 필요한 경우 REQUIRED 입니다. - client-keystore
- 이는 키 저장소 파일의 파일 경로입니다. 이 키 저장소에 어댑터에서 Red Hat Single Sign-On 서버에 HTTPS 요청을 할 때 양방향 SSL에 대한 클라이언트 인증서가 포함되어 있습니다. 이것은 선택 사항입니다.
- client-keystore-password
-
클라이언트 키 저장소의 암호입니다.
client-keystore
가 설정된 경우 REQUIRED 입니다. - client-key-password
-
클라이언트 키의 암호입니다.
client-keystore
가 설정된 경우 REQUIRED 입니다. - always-refresh-token
- true 인 경우 어댑터는 모든 요청에서 토큰을 새로 고칩니다. 경고 - 이 기능을 활성화하면 애플리케이션에 대한 모든 요청에 대해 Red Hat Single Sign-On에 대한 요청이 발생합니다.
- register-node-at-startup
- true 인 경우 어댑터는 Red Hat Single Sign-On에 등록 요청을 보냅니다. 기본적으로 false 이며 애플리케이션이 클러스터될 때만 유용합니다. 자세한 내용은 애플리케이션 할당을 참조하십시오.
- register-node-period
- Red Hat Single Sign-On에 다시 등록된 어댑터 기간. 애플리케이션이 클러스터될 때 유용합니다. 자세한 내용은 애플리케이션 할당을 참조하십시오.
- token-store
- 가능한 값은 세션 및 쿠키 입니다. 기본값은 session 입니다. 즉 어댑터는 HTTP 세션에 계정 정보를 저장합니다. 대체 쿠키는 쿠키 의 정보를 저장함을 의미합니다. 자세한 내용은 애플리케이션 할당을 참조하십시오.
- token-cookie-path
- 쿠키 저장소를 사용하는 경우 이 옵션은 계정 정보를 저장하는 데 사용되는 쿠키의 경로를 설정합니다. 상대 경로인 경우 애플리케이션이 컨텍스트 루트에서 실행되고 해당 컨텍스트 루트와 관련하여 해석되는 것으로 가정합니다. 절대 경로인 경우 절대 경로가 사용되어 쿠키 경로를 설정합니다. 기본값은 컨텍스트 루트와 관련된 경로를 사용합니다.
- principal-attribute
-
OpenID Connect ID 토큰 속성을 사용하여 UserPrincipal 이름을. token 속성이 null인 경우 기본값은
sub
입니다. 가능한 값은sub
,preferred_username
,email
,name
,nickname
,given_name
,family_name
입니다. - turn-off-change-session-id-on-login
- 일부 플랫폼에서 성공적으로 로그인하면 보안 공격 벡터를 연결할 때 세션 ID가 기본적으로 변경됩니다. 이 설정을 해제하려면 이 값을 true로 변경하십시오.이 옵션은 선택 사항입니다. 기본값은 false입니다.
- token-minimum-time-to-live
-
만료되기 전에 Red Hat Single Sign-On 서버를 사용하여 활성 액세스 토큰을 선점하여 새로 고침하는 시간(초)입니다. 이 기능은 평가되기 전에 만료될 수 있는 다른 REST 클라이언트에 액세스 토큰을 보내는 경우에 특히 유용합니다. 이 값은 영역의 액세스 토큰 수명을 초과해서는 안 됩니다. 이것은 선택 사항입니다. 기본값은
0
초이므로 어댑터가 만료된 경우에만 어댑터에서 액세스 토큰을 새로 고칩니다. - min-time-between-jwks-requests
-
새 공개 키를 검색하기 위해 Red Hat Single Sign-On에 대한 두 요청 간 최소 간격을 지정하는 시간(초)입니다. 기본적으로 10초입니다. Adapter는 알 수 없는
아이와
토큰을 인식할 때 항상 새로운 공개 키를 다운로드하려고 합니다. 그러나 10초당 한 번 이상 시도하지 않습니다(기본값). 이는 공격자가 어댑터를 강제 적용하여 Red Hat Single Sign-On에 많은 요청을 보내는 경우 DoS가 발생하지 않도록 하기 위한 것입니다. - public-key-cache-ttl
-
새 공개 키를 검색하기 위해 Red Hat Single Sign-On에 대한 두 요청 간 최대 간격을 지정하는 시간(초)입니다. 기본적으로 86400초(1일)입니다. Adapter는 알 수 없는
아이와
토큰을 인식할 때 항상 새로운 공개 키를 다운로드하려고 합니다. 알려진 문제가 있는 토큰을
인식하는 경우 이전에 다운로드한 공개 키만 사용합니다. 그러나 이 구성된 간격당 한 번 이상(기본적으로 1일)은 토큰에 이미 알려진 경우에도 새 공개 키가 항상 다운로드됩니다. - ignore-oauth-query-parameter
-
기본값은
false
로,true
로 설정되면 전달자 토큰 처리를 위해access_token
쿼리 매개변수 처리가 해제됩니다.access_token
만 통과하면 사용자가 인증할 수 없습니다. - redirect-rewrite-rules
-
필요한 경우 리디렉션 URI 재작성 규칙을 지정합니다. 이는 키가 Redirect URI와 일치해야 하는 정규식이고 값은 대체 문자열인 오브젝트 표기법입니다.
$
문자는 대체 문자열의 역참조에 사용할 수 있습니다. - verify-token-audience
-
true
로 설정하면 어댑터에서 전달자 토큰을 사용한 인증 중에 토큰에 이 클라이언트 이름(리소스)이 대상자로 포함되어 있는지 확인합니다. 옵션은 전달자 토큰에서 인증된 요청을 주로 제공하는 서비스에 특히 유용합니다. 이는 기본적으로false
로 설정되지만 보안 향상을 위해 이를 활성화하는 것이 좋습니다. 대상 지원에 대한 자세한 내용은 support를 참조하십시오.
2.1.2. JBoss EAP 어댑터
ZIP 파일 또는 RPM에서 이 어댑터를 설치할 수 있습니다.
2.1.3. ZIP 파일에서 JBOSS EAP 어댑터 설치
JBoss EAP에 배포된 WAR 애플리케이션을 보호하려면 Red Hat Single Sign-On 어댑터 하위 시스템을 설치하고 구성해야 합니다. WAR를 보호하는 두 가지 옵션이 있습니다.
- WAR에 어댑터 구성 파일을 제공하고 web.xml 내에서 auth-method를 KEYCLOAK로 변경할 수 있습니다.
-
또는 WAR를 전혀 수정할 필요가 없으며
standalone.xml
과 같은 구성 파일의 Red Hat Single Sign-On 어댑터 하위 시스템 구성을 통해 보호할 수 있습니다.
두 방법 모두 이 섹션에 설명되어 있습니다.
어댑터는 사용 중인 서버 버전에 따라 별도의 아카이브로 사용할 수 있습니다.
절차
Sotware Downloads 사이트에서 애플리케이션 서버에 적용되는 어댑터를 설치합니다.
JBoss EAP 7에 설치합니다.
cd $EAP_HOME unzip rh-sso-7.6.11-eap7-adapter.zip
$ cd $EAP_HOME $ unzip rh-sso-7.6.11-eap7-adapter.zip
Copy to Clipboard Copied! 이 ZIP 아카이브에는 Red Hat Single Sign-On 어댑터에 고유한 JBoss 모듈이 포함되어 있습니다. 어댑터 하위 시스템을 구성하는 JBoss CLI 스크립트도 포함되어 있습니다.
어댑터 하위 시스템을 구성하려면 적절한 명령을 실행합니다.
서버가 실행되고 있지 않은 경우 JBoss EAP 7.1 이상에 설치합니다.
./bin/jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
$ ./bin/jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
Copy to Clipboard Copied! 참고JBoss EAP 6.4에서는 오프라인 스크립트를 사용할 수 없습니다.
서버가 실행 중인 경우 JBoss EAP 7.1 이상에 설치합니다.
./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install.cli
$ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install.cli
Copy to Clipboard Copied! 참고JBoss EAP 7.1 이상에서도 레거시 비Elytron 어댑터를 사용할 수 있습니다. 즉,
adapter-install-offline.cli
를 사용할 수 있습니다.참고EAP는 7.4.CP7 및 7.4.CP8 이후 각각 OpenJDK 17 및 Oracle JDK 17을 지원합니다. 새로운 Java 버전은 elytron 변형을 필수이므로 JDK 17의 레거시 어댑터를 사용하지 마십시오. 또한 어댑터 CLI 파일을 실행한 후 EAP에서 제공하는
enable-elytron-se17.cli
스크립트를 실행합니다. elytron 어댑터를 구성하고 호환되지 않는 EAP 하위 시스템을 제거하려면 두 스크립트 모두 필요합니다. 자세한 내용은 이 보안 구성 변경 사항 문서를 참조하십시오.JBoss EAP 6.4에 설치
./bin/jboss-cli.sh -c --file=bin/adapter-install.cli
$ ./bin/jboss-cli.sh -c --file=bin/adapter-install.cli
Copy to Clipboard Copied!
2.1.3.1. JBoss SSO
JBoss EAP는 동일한 JBoss EAP 인스턴스에 배포된 웹 애플리케이션에 대한 SSO(Single Sign-On)를 기본적으로 지원합니다. Red Hat Single Sign-On을 사용할 때는 이 기능을 활성화해서는 안 됩니다.
2.1.3.2. WAR 보안
이 섹션에서는 WAR 패키지에 구성을 추가하고 파일을 편집하여 WAR를 직접 보호하는 방법을 설명합니다.
절차
WAR의 sites
-INF
디렉터리에keycloak.json
어댑터 구성 파일을 생성합니다.이 구성 파일의 형식은 Java 어댑터 구성 섹션에 설명되어 있습니다.
-
web.xml
에서auth-method
를KEYCLOAK
로 설정합니다. 표준 서블릿 보안을 사용하여 URL에 대한 역할 기반 제약 조건을 지정합니다.
예를 들면 다음과 같습니다.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>application</module-name> <security-constraint> <web-resource-collection> <web-resource-name>Admins</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>this is ignored currently</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>application</module-name> <security-constraint> <web-resource-collection> <web-resource-name>Admins</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>this is ignored currently</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
Copy to Clipboard Copied!
2.1.3.3. 어댑터 하위 시스템을 통한 WAR 보안
Red Hat Single Sign-On으로 보안을 위해 WAR를 수정할 필요는 없습니다. 대신 Red Hat SSO(Single Sign-On Adapter)를 통해 외부에서 보호할 수 있습니다. KEYCLOAK을 auth-method
로 지정할 필요는 없지만 web.xml
에서 security-constraints
를 정의해야 합니다. 그러나 WEB-INF/keycloak.json
파일을 만들 필요가 없습니다. 메타데이터는 Red Hat Single Sign-On 하위 시스템 정의의 서버 구성(standalone.xml
) 내에 정의됩니다.
<extensions> <extension module="org.keycloak.keycloak-adapter-subsystem"/> </extensions> <profile> <subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <secure-deployment name="WAR MODULE NAME.war"> <realm>demo</realm> <auth-server-url>http://localhost:8081/auth</auth-server-url> <ssl-required>external</ssl-required> <resource>customer-portal</resource> <credential name="secret">password</credential> </secure-deployment> </subsystem> </profile>
<extensions>
<extension module="org.keycloak.keycloak-adapter-subsystem"/>
</extensions>
<profile>
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
<secure-deployment name="WAR MODULE NAME.war">
<realm>demo</realm>
<auth-server-url>http://localhost:8081/auth</auth-server-url>
<ssl-required>external</ssl-required>
<resource>customer-portal</resource>
<credential name="secret">password</credential>
</secure-deployment>
</subsystem>
</profile>
secure-deployment
이름
속성은 보안하려는 WAR를 식별합니다. 해당 값은 .war
가 추가된 web.xml
에 정의된 module-name
입니다. 나머지 구성은 Java 어댑터 구성에 정의된 keycloak.json
구성 옵션과 함께 1과 거의 일치합니다.
예외는 credential
요소입니다.
보다 쉽게 사용할 수 있도록 Red Hat Single Sign-On 관리 콘솔로 이동하여 이 WAR에 맞게 애플리케이션의 클라이언트/설치 탭으로 이동합니다. 잘라내고 붙여넣을 수 있는 XML 파일 예제를 제공합니다.
동일한 영역에서 보안된 여러 배포가 있는 경우 별도의 요소에서 영역 구성을 공유할 수 있습니다. 예를 들면 다음과 같습니다.
<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <realm name="demo"> <auth-server-url>http://localhost:8080/auth</auth-server-url> <ssl-required>external</ssl-required> </realm> <secure-deployment name="customer-portal.war"> <realm>demo</realm> <resource>customer-portal</resource> <credential name="secret">password</credential> </secure-deployment> <secure-deployment name="product-portal.war"> <realm>demo</realm> <resource>product-portal</resource> <credential name="secret">password</credential> </secure-deployment> <secure-deployment name="database.war"> <realm>demo</realm> <resource>database-service</resource> <bearer-only>true</bearer-only> </secure-deployment> </subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
<realm name="demo">
<auth-server-url>http://localhost:8080/auth</auth-server-url>
<ssl-required>external</ssl-required>
</realm>
<secure-deployment name="customer-portal.war">
<realm>demo</realm>
<resource>customer-portal</resource>
<credential name="secret">password</credential>
</secure-deployment>
<secure-deployment name="product-portal.war">
<realm>demo</realm>
<resource>product-portal</resource>
<credential name="secret">password</credential>
</secure-deployment>
<secure-deployment name="database.war">
<realm>demo</realm>
<resource>database-service</resource>
<bearer-only>true</bearer-only>
</secure-deployment>
</subsystem>
2.1.3.4. 보안 도메인
보안 컨텍스트는 Egress 계층으로 자동 전파됩니다.
2.1.4. RPM에서 JBoss EAP 7 어댑터 설치
Red Hat Enterprise Linux 7에서는 채널이라는 용어가 리포지토리라는 이름으로 교체되었습니다. 이러한 명령에서는 리포지토리라는 용어만 사용됩니다.
사전 요구 사항
RPM에서 JBoss EAP 7 어댑터를 설치하려면 먼저 JBoss EAP 7.4 리포지토리를 구독해야 합니다.
- Red Hat Subscription Manager를 사용하여 Red Hat Enterprise Linux 시스템이 계정에 등록되어 있는지 확인하십시오. 자세한 내용은 Red Hat 서브스크립션 관리 설명서를 참조하십시오.
다른 JBoss EAP 리포지토리를 이미 구독한 경우 해당 리포지토리에서 먼저 구독 해제해야 합니다.
Red Hat Enterprise Linux 6, 7의 경우 7: Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 7.4 리포지토리를 구독하십시오. <RHEL_VERSION>을 Red Hat Enterprise Linux 버전에 따라 6 또는 7로 바꿉니다.
sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
Copy to Clipboard Copied! Red Hat Enterprise Linux 8의 경우: Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 7.4 리포지터리를 구독하십시오.
sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
$ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
Copy to Clipboard Copied!
절차
Red Hat Enterprise Linux 버전에 따라 OIDC용 JBoss EAP 7 어댑터를 설치합니다.
Red Hat Enterprise Linux 6, 7에 설치합니다.
sudo yum install eap7-keycloak-adapter-sso7_6
$ sudo yum install eap7-keycloak-adapter-sso7_6
Copy to Clipboard Copied! Red Hat Enterprise Linux 8에 설치합니다.
sudo dnf install eap7-keycloak-adapter-sso7_6
$ sudo dnf install eap7-keycloak-adapter-sso7_6
Copy to Clipboard Copied! 참고RPM 설치의 기본 EAP_HOME 경로는 /opt/rh/eap7/root/usr/share/wildfly입니다.
OIDC 모듈에 대한 설치 스크립트를 실행합니다.
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
Copy to Clipboard Copied!
설치가 완료되었습니다.
2.1.5. RPM에서 JBoss EAP 6 어댑터 설치
Red Hat Enterprise Linux 7에서는 채널이라는 용어가 리포지토리라는 이름으로 교체되었습니다. 이러한 명령에서는 리포지토리라는 용어만 사용됩니다.
RPM에서 EAP 6 어댑터를 설치하려면 먼저 JBoss EAP 6 리포지토리를 구독해야 합니다.
사전 요구 사항
- Red Hat Subscription Manager를 사용하여 Red Hat Enterprise Linux 시스템이 계정에 등록되어 있는지 확인하십시오. 자세한 내용은 Red Hat 서브스크립션 관리 설명서를 참조하십시오.
다른 JBoss EAP 리포지토리를 이미 구독한 경우 해당 리포지토리에서 먼저 구독 해제해야 합니다.
Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 6 리포지토리를 구독하십시오. <RHEL_VERSION>을 Red Hat Enterprise Linux 버전에 따라 6 또는 7로 바꿉니다.
sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
Copy to Clipboard Copied!
절차
다음 명령을 사용하여 OIDC용 EAP 6 어댑터를 설치합니다.
sudo yum install keycloak-adapter-sso7_6-eap6
$ sudo yum install keycloak-adapter-sso7_6-eap6
Copy to Clipboard Copied! 참고RPM 설치의 기본 EAP_HOME 경로는 /opt/rh/eap6/root/usr/share/wildfly입니다.
OIDC 모듈에 대한 설치 스크립트를 실행합니다.
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
Copy to Clipboard Copied!
설치가 완료되었습니다.
2.1.6. JBoss Fuse 6 어댑터
Red Hat Single Sign-On은 JBoss Fuse 6 내에서 실행되는 웹 애플리케이션 보안을 지원합니다.
지원되는 유일한 버전의 Fuse 6은 최신 버전입니다. 이전 버전의 Fuse 6을 사용하는 경우 일부 기능이 제대로 작동하지 않을 수 있습니다. 특히 Hawtio 통합은 이전 버전의 Fuse 6에서 작동하지 않습니다.
Fuse에서 다음 항목에 대한 보안이 지원됩니다.
- Pax Web comes Extender를 사용하여 Fuse에 배포된 클래식 WAR 애플리케이션
- Pax Web whiteboard Extender를 사용하여 Fuse에 OSGI 서비스로 배포된 서블릿
- Camelkafkaty 구성 요소를 사용하여 실행 중인 Apache Camel Cryostatty 끝점
- 자체적인 192.0.2.ty 엔진에서 실행되는 Apache CXF 엔드 포인트 https://cxf.apache.org/docs/jetty-configuration.html
- CXF 서블릿에서 제공하는 기본 엔진에서 실행되는 Apache CXF 끝점
- SSH 및 Cryostat 관리자 액세스
- Hawtio 관리 콘솔
2.1.6.1. Fuse 6 내에서 웹 애플리케이션 보안
먼저 Red Hat Single Sign-On Karaf 기능을 설치해야 합니다. 다음으로 보안하려는 애플리케이션 유형에 따라 단계를 수행해야 합니다. 참조된 모든 웹 애플리케이션에서는 Red Hat Single Sign-On Cryostatty 인증기를 기본 Cryostat 서버에 삽입해야 합니다. 이를 수행하는 단계는 애플리케이션 유형에 따라 다릅니다. 자세한 내용은 아래에 설명되어 있습니다.
2.1.6.2. Keycloak 기능 설치
먼저 JBoss Fuse 환경에 keycloak
기능을 설치해야 합니다. keycloak 기능에는 Fuse 어댑터와 모든 타사 종속 항목이 포함되어 있습니다. Maven 리포지토리 또는 아카이브에서 설치할 수 있습니다.
2.1.6.2.1. Maven 리포지토리에서 설치
사전 요구 사항
- 온라인 상태여야 하며 Maven 리포지토리에 액세스할 수 있어야 합니다.
Red Hat Single Sign-On의 경우 아티팩트를 설치할 수 있도록 적절한 Maven 리포지토리를 구성합니다. 자세한 내용은 JBoss Enterprise Maven 리포지토리 페이지를 참조하십시오.
Maven 리포지토리가 https://maven.repository.redhat.com/ga/ 이라고 가정하고
$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg
파일에 다음을 추가하고 지원되는 리포지토리 목록에 리포지토리를 추가합니다. 예를 들면 다음과 같습니다.org.ops4j.pax.url.mvn.repositories= \ https://maven.repository.redhat.com/ga/@id=redhat.product.repo http://repo1.maven.org/maven2@id=maven.central.repo, \ ...
org.ops4j.pax.url.mvn.repositories= \ https://maven.repository.redhat.com/ga/@id=redhat.product.repo http://repo1.maven.org/maven2@id=maven.central.repo, \ ...
Copy to Clipboard Copied!
절차
- JBoss Fuse 6.3.0 롤업 12를 시작합니다.
Karaf 터미널 유형에서 다음을 수행합니다.
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
Copy to Clipboard Copied! 또한 9 기능을 설치해야 할 수도 있습니다.
features:install keycloak-jetty9-adapter
features:install keycloak-jetty9-adapter
Copy to Clipboard Copied! 기능이 설치되었는지 확인합니다.
features:list | grep keycloak
features:list | grep keycloak
Copy to Clipboard Copied!
2.1.6.2.2. ZIP 번들에서 설치
이 설치 옵션은 오프라인 상태이거나 Maven을 사용하여 JAR 파일 및 기타 아티팩트를 가져오지 않으려는 경우에 유용합니다.
절차
- Sotware 다운로드 사이트에서 Red Hat Single Sign-On Fuse 어댑터 ZIP 아카이브를 다운로드합니다.
JBoss Fuse의 루트 디렉터리에 압축을 풉니다. 그런 다음 종속 항목은
시스템
디렉터리 아래에 설치됩니다. 기존의 모든 files를 덮어쓸 수 있습니다.JBoss Fuse 6.3.0 롤업 12에 이 정보를 사용합니다.
cd /path-to-fuse/jboss-fuse-6.3.0.redhat-254 unzip -q /path-to-adapter-zip/rh-sso-7.6.11-fuse-adapter.zip
cd /path-to-fuse/jboss-fuse-6.3.0.redhat-254 unzip -q /path-to-adapter-zip/rh-sso-7.6.11-fuse-adapter.zip
Copy to Clipboard Copied! Fuse를 시작하고 fuse/karaf 터미널에서 다음 명령을 실행합니다.
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
Copy to Clipboard Copied! -
해당 deltaty 어댑터를 설치합니다. JBoss Fuse
시스템
디렉터리에서 아티팩트를 직접 사용할 수 있으므로 Maven 리포지토리를 사용할 필요가 없습니다.
2.1.6.3. Classic WAR 애플리케이션 보안
절차
/WEB-INF/web.xml
파일에서 필요한 내용을 선언합니다.- <security-constraint> 요소의 보안 제약 조건
- <login-config> 요소의 로그인 구성
<security-role> 요소의 보안 역할.
예를 들면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
Copy to Clipboard Copied!
Authenticator가 포함된
jetty-web.xml
파일을/WEB-INF/jetty-web.xml
파일에 추가합니다.예를 들면 다음과 같습니다.
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get name="securityHandler"> <Set name="authenticator"> <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> </New> </Set> </Get> </Configure>
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get name="securityHandler"> <Set name="authenticator"> <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> </New> </Set> </Get> </Configure>
Copy to Clipboard Copied! -
WAR의
/WEB-INF/
디렉터리에 새 파일 keycloak.json을 생성합니다. 이 구성 파일의 형식은 Java Adapters Config 섹션에 설명되어 있습니다. 외부 어댑터 구성에 설명된 대로 이 파일을 외부에서 사용할 수도 있습니다. WAR 애플리케이션이
Import-Package
헤더 아래의org.keycloak.adapters.jetty
및META-INF/MANIFEST.MF
파일에서 더 많은 패키지를 가져오는지 확인합니다. 프로젝트에서maven-bundle-plugin
을 사용하면 매니페스트에 OSGI 헤더가 올바르게 생성됩니다. 패키지의 "*" 해상도는 애플리케이션 또는 블루프린트 또는 Spring 설명자에서 사용되지 않으므로org.keycloak.adapters.jetty
패키지를 가져오지 않지만jetty-web.xml
파일에서 사용됩니다.가져올 패키지 목록은 다음과 같습니다.
org.keycloak.adapters.jetty;version="18.0.18.redhat-00001", org.keycloak.adapters;version="18.0.18.redhat-00001", org.keycloak.constants;version="18.0.18.redhat-00001", org.keycloak.util;version="18.0.18.redhat-00001", org.keycloak.*;version="18.0.18.redhat-00001", *;resolution:=optional
org.keycloak.adapters.jetty;version="18.0.18.redhat-00001", org.keycloak.adapters;version="18.0.18.redhat-00001", org.keycloak.constants;version="18.0.18.redhat-00001", org.keycloak.util;version="18.0.18.redhat-00001", org.keycloak.*;version="18.0.18.redhat-00001", *;resolution:=optional
Copy to Clipboard Copied!
2.1.6.3.1. 외부 어댑터 구성
keycloak.json
어댑터 구성 파일을 WAR 애플리케이션 내에 번들링하지 않고 대신 외부에서 사용할 수 있고 이름 지정 규칙을 기반으로 로드되는 경우 이 구성 방법을 사용합니다.
기능을 활성화하려면 이 섹션을 /WEB_INF/web.xml
파일에 추가하십시오.
<context-param> <param-name>keycloak.config.resolver</param-name> <param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value> </context-param>
<context-param>
<param-name>keycloak.config.resolver</param-name>
<param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value>
</context-param>
해당 구성 요소는 keycloak.config
또는 karaf.etc
java 속성을 사용하여 기본 폴더를 검색하여 구성을 찾습니다. 그런 다음 해당 폴더 중 하나에서 < your_web_context>-keycloak.json
이라는 파일을 검색합니다.
예를 들어 웹 애플리케이션에 컨텍스트 my-portal
이 있는 경우 $FUSE_HOME/etc/my-portal-keycloak.json
파일에서 어댑터 구성이 로드됩니다.
2.1.6.4. OSGI 서비스로 배포된 서블릿 보안
기존 WAR 애플리케이션으로 배포되지 않은 OSGI 번들 프로젝트 내부에 서블릿 클래스가 있는 경우 이 방법을 사용할 수 있습니다. Fuse는 Pax Web whiteboard Extender를 사용하여 웹 애플리케이션과 같은 서블릿을 배포합니다.
절차
Red Hat Single Sign-On은
org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService
를 제공하여 애플리케이션에 대한 jetty-web.xml 삽입 및 보안 제약 조건을 구성할 수 있습니다. 애플리케이션 내부에OSGI-INF/blueprint/blueprint.xml
파일에서 이러한 서비스를 선언해야 합니다. 서블릿은 이에 따라 달라야 합니다. 예제 구성:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!-- Using jetty bean just for the compatibility with other fuse services --> <bean id="servletConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint"> <bean class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="cst1"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> </property> <property name="pathSpec" value="/product-portal/*"/> </bean> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" /> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration"> </bean> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!-- Using jetty bean just for the compatibility with other fuse services --> <bean id="servletConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint"> <bean class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="cst1"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> </property> <property name="pathSpec" value="/product-portal/*"/> </bean> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" /> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration"> </bean> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
Copy to Clipboard Copied! -
Classic WAR 애플리케이션 섹션과 같이 프로젝트 내부에
WEB-INF
디렉토리를 사용하고(프로젝트가 웹 애플리케이션이 아니더라도)/gateway-INF/jetty-web.xml
및/WEB-INF/keycloak.json
파일을 생성해야 할 수 있습니다. security-constraints가 블루프린트 구성 파일에 선언되므로web.xml
파일이 필요하지 않습니다.
-
Classic WAR 애플리케이션 섹션과 같이 프로젝트 내부에
META-INF/MANIFEST.MF
의Import-Package
에는 최소한 다음 가져오기가 포함되어야 합니다.org.keycloak.adapters.jetty;version="18.0.18.redhat-00001", org.keycloak.adapters;version="18.0.18.redhat-00001", org.keycloak.constants;version="18.0.18.redhat-00001", org.keycloak.util;version="18.0.18.redhat-00001", org.keycloak.*;version="18.0.18.redhat-00001", *;resolution:=optional
org.keycloak.adapters.jetty;version="18.0.18.redhat-00001", org.keycloak.adapters;version="18.0.18.redhat-00001", org.keycloak.constants;version="18.0.18.redhat-00001", org.keycloak.util;version="18.0.18.redhat-00001", org.keycloak.*;version="18.0.18.redhat-00001", *;resolution:=optional
Copy to Clipboard Copied!
2.1.6.5. Apache Camel 애플리케이션 보안
KeycloakJettyAuthenticator
및 적절한 보안 제약 조건을 사용하여 securityHandler를 추가하여 camel-jetty 구성 요소로 구현된 Apache Camel 엔드포인트를 보호할 수 있습니다. 다음과 같은 구성으로 Camel 애플리케이션에 OSGI-INF/blueprint/blueprint.xml
파일을 추가할 수 있습니다. 역할, 보안 제약 조건 매핑 및 Red Hat Single Sign-On 어댑터 구성은 환경과 필요에 따라 약간 다를 수 있습니다.
예를 들면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/blueprint" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> <bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig"> <property name="realm" value="demo"/> <property name="resource" value="admin-camel-endpoint"/> <property name="bearerOnly" value="true"/> <property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="sslRequired" value="EXTERNAL"/> </bean> <bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> <property name="adapterConfig" ref="kcAdapterConfig"/> </bean> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="Customers"/> <property name="roles"> <list> <value>admin</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref component-id="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <bean id="sessionHandler" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler"> <property name="handler" ref="securityHandler" /> </bean> <bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" /> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route id="httpBridge"> <from uri="jetty:http://0.0.0.0:8383/admin-camel-endpoint?handlers=sessionHandler&matchOnUriPrefix=true" /> <process ref="helloProcessor" /> <log message="The message from camel endpoint contains ${body}"/> </route> </camelContext> </blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig">
<property name="realm" value="demo"/>
<property name="resource" value="admin-camel-endpoint"/>
<property name="bearerOnly" value="true"/>
<property name="authServerUrl" value="http://localhost:8080/auth" />
<property name="sslRequired" value="EXTERNAL"/>
</bean>
<bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
<property name="adapterConfig" ref="kcAdapterConfig"/>
</bean>
<bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="Customers"/>
<property name="roles">
<list>
<value>admin</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
<bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator" ref="keycloakAuthenticator" />
<property name="constraintMappings">
<list>
<ref component-id="constraintMapping" />
</list>
</property>
<property name="authMethod" value="BASIC"/>
<property name="realmName" value="does-not-matter"/>
</bean>
<bean id="sessionHandler" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler">
<property name="handler" ref="securityHandler" />
</bean>
<bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" />
<camelContext id="blueprintContext"
trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<route id="httpBridge">
<from uri="jetty:http://0.0.0.0:8383/admin-camel-endpoint?handlers=sessionHandler&matchOnUriPrefix=true" />
<process ref="helloProcessor" />
<log message="The message from camel endpoint contains ${body}"/>
</route>
</camelContext>
</blueprint>
-
META-INF/MANIFEST의
에는 다음 가져오기가 포함되어야 합니다.Import-Package
.MF
javax.servlet;version="[3,4)", javax.servlet.http;version="[3,4)", org.apache.camel.*, org.apache.camel;version="[2.13,3)", org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.server.nio;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.18.redhat-00001", org.osgi.service.blueprint, org.osgi.service.blueprint.container, org.osgi.service.event,
javax.servlet;version="[3,4)",
javax.servlet.http;version="[3,4)",
org.apache.camel.*,
org.apache.camel;version="[2.13,3)",
org.eclipse.jetty.security;version="[9,10)",
org.eclipse.jetty.server.nio;version="[9,10)",
org.eclipse.jetty.util.security;version="[9,10)",
org.keycloak.*;version="18.0.18.redhat-00001",
org.osgi.service.blueprint,
org.osgi.service.blueprint.container,
org.osgi.service.event,
2.1.6.6. Camel RestDSL
Camel RestDSL은 유창한 방식으로 REST 엔드포인트를 정의하는 데 사용되는 Camel 기능입니다. 그러나 특정 구현 클래스를 계속 사용하고 Red Hat Single Sign-On과 통합하는 방법에 대한 지침을 제공해야 합니다.
통합 메커니즘을 구성하는 방법은 RestDSL 정의 경로를 구성하는 Camel 구성 요소에 따라 다릅니다.
다음 예제에서는 이전 블루프린트 예제에 정의된 일부 빈에 대한 참조와 함께 Cryostat 구성 요소를 사용하여 통합을 구성하는 방법을 보여줍니다.
<bean id="securityHandlerRest" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref component-id="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <bean id="sessionHandlerRest" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler"> <property name="handler" ref="securityHandlerRest" /> </bean> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <restConfiguration component="jetty" contextPath="/restdsl" port="8484"> <!--the link with Keycloak security handlers happens here--> <endpointProperty key="handlers" value="sessionHandlerRest"></endpointProperty> <endpointProperty key="matchOnUriPrefix" value="true"></endpointProperty> </restConfiguration> <rest path="/hello" > <description>Hello rest service</description> <get uri="/{id}" outType="java.lang.String"> <description>Just an helllo</description> <to uri="direct:justDirect" /> </get> </rest> <route id="justDirect"> <from uri="direct:justDirect"/> <process ref="helloProcessor" /> <log message="RestDSL correctly invoked ${body}"/> <setBody> <constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant> </setBody> </route> </camelContext>
<bean id="securityHandlerRest" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator" ref="keycloakAuthenticator" />
<property name="constraintMappings">
<list>
<ref component-id="constraintMapping" />
</list>
</property>
<property name="authMethod" value="BASIC"/>
<property name="realmName" value="does-not-matter"/>
</bean>
<bean id="sessionHandlerRest" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler">
<property name="handler" ref="securityHandlerRest" />
</bean>
<camelContext id="blueprintContext"
trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<restConfiguration component="jetty" contextPath="/restdsl"
port="8484">
<!--the link with Keycloak security handlers happens here-->
<endpointProperty key="handlers" value="sessionHandlerRest"></endpointProperty>
<endpointProperty key="matchOnUriPrefix" value="true"></endpointProperty>
</restConfiguration>
<rest path="/hello" >
<description>Hello rest service</description>
<get uri="/{id}" outType="java.lang.String">
<description>Just an helllo</description>
<to uri="direct:justDirect" />
</get>
</rest>
<route id="justDirect">
<from uri="direct:justDirect"/>
<process ref="helloProcessor" />
<log message="RestDSL correctly invoked ${body}"/>
<setBody>
<constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant>
</setBody>
</route>
</camelContext>
2.1.6.7. 별도의 192.0.2.ty 엔진에서 Apache CXF 엔드포인트 보안
절차
별도의 Fromty 엔진에서 Red Hat Single Sign-On에서 보안한 CXF 엔드포인트를 실행하려면 다음 절차를 수행합니다.
애플리케이션에
META-INF/spring/beans.xml
을 추가하고, 이 경우 KeycloakJettyAuthenticator가 삽입된KeycloakJettyAuthenticator
와 함께httpj:engine-factory
를 선언합니다. CFX Cryostat-WS 애플리케이션의 구성은 다음과 유사할 수 있습니다.<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig"> <property name="realm" value="demo"/> <property name="resource" value="custom-cxf-endpoint"/> <property name="bearerOnly" value="true"/> <property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="sslRequired" value="EXTERNAL"/> </bean> <bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> <property name="adapterConfig"> <ref local="kcAdapterConfig" /> </property> </bean> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="Customers"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref local="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <httpj:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpj:engine port="8282"> <httpj:handlers> <ref local="securityHandler" /> </httpj:handlers> <httpj:sessionSupport>true</httpj:sessionSupport> </httpj:engine> </httpj:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint" /> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig"> <property name="realm" value="demo"/> <property name="resource" value="custom-cxf-endpoint"/> <property name="bearerOnly" value="true"/> <property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="sslRequired" value="EXTERNAL"/> </bean> <bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> <property name="adapterConfig"> <ref local="kcAdapterConfig" /> </property> </bean> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="Customers"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref local="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <httpj:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpj:engine port="8282"> <httpj:handlers> <ref local="securityHandler" /> </httpj:handlers> <httpj:sessionSupport>true</httpj:sessionSupport> </httpj:engine> </httpj:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint" /> </beans>
Copy to Clipboard Copied! CXF Cryostat-RS 애플리케이션의 경우 engine-factory에 따라 끝점의 구성에 차이가 있을 수 있습니다.
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
Copy to Clipboard Copied! -
META-INF/MANIFEST.MF
의Import-Package
에는 이러한 가져오기가 포함되어야 합니다.
META-INF.cxf;version="[2.7,3.2)", META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional, org.apache.cxf.bus;version="[2.7,3.2)", org.apache.cxf.bus.spring;version="[2.7,3.2)", org.apache.cxf.bus.resource;version="[2.7,3.2)", org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", org.springframework.beans.factory.config, org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.18.redhat-00001"
META-INF.cxf;version="[2.7,3.2)",
META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional,
org.apache.cxf.bus;version="[2.7,3.2)",
org.apache.cxf.bus.spring;version="[2.7,3.2)",
org.apache.cxf.bus.resource;version="[2.7,3.2)",
org.apache.cxf.transport.http;version="[2.7,3.2)",
org.apache.cxf.*;version="[2.7,3.2)",
org.springframework.beans.factory.config,
org.eclipse.jetty.security;version="[9,10)",
org.eclipse.jetty.util.security;version="[9,10)",
org.keycloak.*;version="18.0.18.redhat-00001"
2.1.6.8. 기본 CXF 엔진에서 Apache CXF 끝점 보안
일부 서비스는 시작 시 배포된 서블릿과 함께 자동으로 제공됩니다. 이러한 서비스 중 하나는 http://localhost:8181/cxf 컨텍스트에서 실행되는 CXF 서블릿입니다. 이러한 끝점을 보호하는 것은 복잡할 수 있습니다. Red Hat Single Sign-On이 현재 사용 중인 한 가지 접근 방식은 시작 시 기본 제공 서블릿을 배포 취소하는 ServletReregistrationService로, Red Hat Single Sign-On이 보호하는 컨텍스트에 재배포할 수 있습니다.
애플리케이션 내의 구성 파일 OSGI-INF/blueprint/blueprint.xml
은 아래 파일과 유사할 수 있습니다. 애플리케이션에 고유한 엔드포인트인 Cryostat-RS customerservice
엔드포인트를 추가하지만 더 중요한 것은 전체 /cxf
컨텍스트를 보호합니다.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> <!-- JAXRS Application --> <bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" /> <jaxrs:server id="cxfJaxrsServer" address="/customerservice"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> <jaxrs:serviceBeans> <ref component-id="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> <!-- Securing of whole /cxf context by unregister default cxf servlet from paxweb and re-register with applied security constraints --> <bean id="cxfConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint"> <bean class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="cst1"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> </property> <property name="pathSpec" value="/cxf/*"/> </bean> <bean id="cxfKeycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" /> <property name="constraintMappings"> <list> <ref component-id="cxfConstraintMapping" /> </list> </property> </bean> <bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="managedServiceReference"> <reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000" /> </property> </bean> </blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd">
<!-- JAXRS Application -->
<bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" />
<jaxrs:server id="cxfJaxrsServer" address="/customerservice">
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</jaxrs:providers>
<jaxrs:serviceBeans>
<ref component-id="customerBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<!-- Securing of whole /cxf context by unregister default cxf servlet from paxweb and re-register with applied security constraints -->
<bean id="cxfConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint">
<bean class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="cst1"/>
<property name="roles">
<list>
<value>user</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
</property>
<property name="pathSpec" value="/cxf/*"/>
</bean>
<bean id="cxfKeycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService"
init-method="start" destroy-method="stop">
<property name="bundleContext" ref="blueprintBundleContext" />
<property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" />
<property name="constraintMappings">
<list>
<ref component-id="cxfConstraintMapping" />
</list>
</property>
</bean>
<bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration"
init-method="start" destroy-method="stop">
<property name="bundleContext" ref="blueprintBundleContext" />
<property name="managedServiceReference">
<reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000" />
</property>
</bean>
</blueprint>
결과적으로 기본 CXF HTTP 대상에서 실행되는 다른 모든 CXF 서비스도 보호됩니다. 마찬가지로 애플리케이션이 배포 취소되면 전체 /cxf
컨텍스트도 안전하지 않습니다. 이러한 이유로 별도의 CXF 엔진의 Secure CXF Application에 설명된 대로 애플리케이션에 고유한 Cryostat 엔진 을 사용하면 각 개별 애플리케이션에 대한 보안을 보다 효과적으로 제어할 수 있습니다.
-
WEB-INF
디렉토리는 프로젝트 내부에 있어야 할 수 있습니다(프로젝트가 웹 애플리케이션이 아닌 경우에도). 또한 Classic WAR 애플리케이션에서 와 유사한 방식으로/WEB-INF/jetty-web.xml
및/WEB-INF/keycloak.json
파일을 편집해야 할 수도 있습니다. 보안 제약 조건이 블루프린트 구성 파일에 선언되므로web.xml
파일이 필요하지 않습니다. -
META-INF/MANIFEST.MF
의Import-Package
에는 다음 가져오기가 포함되어야 합니다.
META-INF.cxf;version="[2.7,3.2)", META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional, org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", com.fasterxml.jackson.jaxrs.json;version="[2.5,3)", org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.18.redhat-00001", org.keycloak.adapters.jetty;version="18.0.18.redhat-00001", *;resolution:=optional
META-INF.cxf;version="[2.7,3.2)",
META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional,
org.apache.cxf.transport.http;version="[2.7,3.2)",
org.apache.cxf.*;version="[2.7,3.2)",
com.fasterxml.jackson.jaxrs.json;version="[2.5,3)",
org.eclipse.jetty.security;version="[9,10)",
org.eclipse.jetty.util.security;version="[9,10)",
org.keycloak.*;version="18.0.18.redhat-00001",
org.keycloak.adapters.jetty;version="18.0.18.redhat-00001",
*;resolution:=optional
2.1.6.9. Fuse 관리 서비스 보안
2.1.6.9.1. SSH 인증으로 Fuse 터미널 사용
Red Hat Single Sign-On은 주로 웹 애플리케이션의 인증에 대한 사용 사례를 다루지만 다른 웹 서비스 및 애플리케이션이 Red Hat Single Sign-On으로 보호되는 경우 Red Hat Single Sign-On 인증 정보를 사용한 SSH와 같은 비 웹 관리 서비스를 보호하는 것이 가장 좋습니다. Red Hat Single Sign-On에 대한 원격 연결을 허용하고 리소스 소유자 암호 자격 증명을 기반으로 인증 정보를 확인하는 JAAS 로그인 모듈을 사용하여 이 작업을 수행할 수 있습니다.
SSH 인증을 활성화하려면 다음 절차를 수행합니다.
절차
-
Red Hat Single Sign-On에서 SSH 인증에 사용할 클라이언트(예:
ssh-jmx-admin-client
)를 만듭니다. 이 클라이언트에는직접 액세스 권한 부여가 설정되어
있어야 합니다. $FUSE_HOME/etc/org.apache.karaf.shell.cfg
파일에서 이 속성을 업데이트하거나 지정합니다.sshRealm=keycloak
sshRealm=keycloak
Copy to Clipboard Copied! 환경 및 Red Hat Single Sign-On 클라이언트 설정에 따라 다음과 유사한 콘텐츠를 사용하여
$FUSE_HOME/etc/keycloak-direct-access.json
파일을 추가합니다.{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
Copy to Clipboard Copied! 이 파일은 SSH 인증을 위해
keycloak
JAAS 영역의 JAAS DirectAccessGrantsLoginModule에서 사용하는 클라이언트 애플리케이션 구성을 지정합니다.Fuse를 시작하고
keycloak
JAAS 영역을 설치합니다. 가장 쉬운 방법은 JAAS 영역이 사전 정의된keycloak-jaas
기능을 설치하는 것입니다. 순위가 높은 자체keycloak
JAAS 영역을 사용하여 기능의 사전 정의된 영역을 재정의할 수 있습니다. 자세한 내용은 JBoss Fuse 설명서 를 참조하십시오.Fuse 터미널에서 다음 명령을 사용하십시오.
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak-jaas
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak-jaas
Copy to Clipboard Copied! 터미널에 다음을 입력하여 SSH를
admin
사용자로 사용하여 로그인합니다.ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
Copy to Clipboard Copied! -
암호 를 사용하여
로그인합니다
.
일부 이후 운영 체제에서는 SSH 명령의 -o 옵션 -o HostKeyAlgorithms=+ssh-dss
를 사용해야 할 수도 있습니다. 이후 SSH 클라이언트는 기본적으로 ssh-dss
알고리즘 사용을 허용하지 않기 때문입니다. 그러나 기본적으로 현재 JBoss Fuse 6.3.0 롤업 12에서 사용됩니다.
사용자에게 모든 작업을 수행하거나 작업 하위 집합을 수행하려면 영역 역할 admin
이 있어야 합니다(예: 사용자가 읽기 전용 Karaf 명령만 실행하도록 제한하는 뷰어 역할). 사용 가능한 역할은 $FUSE_HOME/etc/org.apache.karaf.shell.cfg
또는 $FUSE_HOME/etc/system.properties
에서 구성됩니다.
2.1.6.9.2. Cryostat 인증 사용
jconsole 또는 다른 외부 툴을 사용하여 RMI를 통해 remotely에 연결하려는 경우 Cryostat 인증이 필요할 수 있습니다. 그렇지 않으면 jolokia 에이전트가 기본적으로 hawt.io에 설치되므로 hawt.io/jolokia를 사용하는 것이 더 좋습니다. 자세한 내용은 Hawtio 관리 콘솔을 참조하십시오.
절차
$FUSE_HOME/etc/org.apache.karaf.management.cfg
파일에서 jmxRealm 속성을 다음과 같이 변경합니다.jmxRealm=keycloak
jmxRealm=keycloak
Copy to Clipboard Copied! -
위의 SSH 섹션에 설명된 대로
keycloak-jaas
기능을 설치하고$FUSE_HOME/etc/keycloak-direct-access.json
파일을 구성합니다. - jconsole에서는 다음과 같은 URL을 사용할 수 있습니다.
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
및 인증 정보: admin/password(사용자 환경에 따라 관리자 권한이 있는 사용자 기반).
2.1.6.10. Hawtio 관리 콘솔 보안
Red Hat Single Sign-On을 사용하여 Hawtio 관리 콘솔을 보호하려면 다음 절차를 수행합니다.
절차
$FUSE_HOME/etc/system.properties
파일에 이러한 속성을 추가합니다.hawtio.keycloakEnabled=true hawtio.realm=keycloak hawtio.keycloakClientConfig=file://${karaf.base}/etc/keycloak-hawtio-client.json hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
hawtio.keycloakEnabled=true hawtio.realm=keycloak hawtio.keycloakClientConfig=file://${karaf.base}/etc/keycloak-hawtio-client.json hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
Copy to Clipboard Copied! -
해당 영역의 Red Hat Single Sign-On 관리 콘솔에서 클라이언트를 생성합니다. 예를 들어 Red Hat Single Sign-On
데모
영역에서 클라이언트hawtio-client
를 생성하고, 액세스 유형으로public
을 지정하고, Hawtio: http://localhost:8181/hawtio/*를 가리키는 리디렉션 URI를 지정합니다. 또한 해당 Web Origin이 구성되어 있어야 합니다(이 경우 http://localhost:8181). -
아래 예제와 유사한 내용을 사용하여
$FUSE_HOME/etc
디렉터리에keycloak-hawtio-client.json
파일을 생성합니다. Red Hat Single Sign-On 환경에 따라 ,리소스
,auth-server-url
속성을 변경합니다.resource
속성은 이전 단계에서 생성한 클라이언트를 가리켜야 합니다. 이 파일은 클라이언트(Hawtio JavaScript 애플리케이션) 측에서 사용합니다.
{ "realm" : "demo", "resource" : "hawtio-client", "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "public-client" : true }
{
"realm" : "demo",
"resource" : "hawtio-client",
"auth-server-url" : "http://localhost:8080/auth",
"ssl-required" : "external",
"public-client" : true
}
아래 예제와 유사한 내용을 사용하여
$FUSE_HOME/etc
dicrectory에keycloak-hawtio.json
파일을 생성합니다. Red Hat Single Sign-On 환경에 따라realm
및auth-server-url
속성을 변경합니다. 이 파일은 서버의 어댑터 (JAAS 로그인 모듈) 측에서 사용됩니다.{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
Copy to Clipboard Copied! JBoss Fuse 6.3.0 롤업 12를 시작하고 아직 수행하지 않은 경우 키클로킹 기능을 설치합니다. Karaf 터미널의 명령은 다음 예와 유사합니다.
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak
Copy to Clipboard Copied! http://localhost:8181/hawtio 으로 이동하여 Red Hat Single Sign-On 영역에서 사용자로 로그인합니다.
사용자가 Hawtio에 성공적으로 인증하려면 적절한 realm 역할이 있어야 합니다. 사용 가능한 역할은
hawtio.roles
의$FUSE_HOME/etc/system.properties
파일에서 구성됩니다.
2.1.6.10.1. JBoss EAP 6.4에서 Hawtio 보안
사전 요구 사항
Hawtio 관리 콘솔 보안에 설명된 대로 Red Hat Single Sign-On을 설정합니다. 다음과 같이 가정합니다.
-
Red Hat Single Sign-On 영역
데모
및 클라이언트hawtio-client
가 있습니다. -
Red Hat Single Sign-On은
localhost:8080
에서 실행됩니다. -
배포된 Hawtio가 있는 JBoss EAP 6.4 서버는
localhost:8181
에서 실행됩니다. 이 서버가 있는 디렉터리를$EAP_HOME
이라고 합니다.
절차
-
hawtio-wildfly-1.4.0.redhat-630396.war
아카이브를$EAP_HOME/standalone/configuration
디렉터리에 복사합니다. Hawtio 배포에 대한 자세한 내용은 Fuse Hawtio 설명서 를 참조하십시오. -
위 콘텐츠가 포함된
keycloak-hawtio.json
및keycloak-hawtio-client.json
파일을$EAP_HOME/standalone/configuration
디렉터리에 복사합니다. - JBoss 어댑터 설명서에 설명된 대로 Red Hat Single Sign-On 어댑터 하위 시스템을 JBoss EAP 6.4 서버에 설치합니다.
$EAP_HOME/standalone/configuration/standalone.xml
파일에서 다음 예와 같이 시스템 속성을 구성합니다.<extensions> ... </extensions> <system-properties> <property name="hawtio.authenticationEnabled" value="true" /> <property name="hawtio.realm" value="hawtio" /> <property name="hawtio.roles" value="admin,viewer" /> <property name="hawtio.rolePrincipalClasses" value="org.keycloak.adapters.jaas.RolePrincipal" /> <property name="hawtio.keycloakEnabled" value="true" /> <property name="hawtio.keycloakClientConfig" value="${jboss.server.config.dir}/keycloak-hawtio-client.json" /> <property name="hawtio.keycloakServerConfig" value="${jboss.server.config.dir}/keycloak-hawtio.json" /> </system-properties>
<extensions> ... </extensions> <system-properties> <property name="hawtio.authenticationEnabled" value="true" /> <property name="hawtio.realm" value="hawtio" /> <property name="hawtio.roles" value="admin,viewer" /> <property name="hawtio.rolePrincipalClasses" value="org.keycloak.adapters.jaas.RolePrincipal" /> <property name="hawtio.keycloakEnabled" value="true" /> <property name="hawtio.keycloakClientConfig" value="${jboss.server.config.dir}/keycloak-hawtio-client.json" /> <property name="hawtio.keycloakServerConfig" value="${jboss.server.config.dir}/keycloak-hawtio.json" /> </system-properties>
Copy to Clipboard Copied! security-domains
섹션의 동일한 파일에 Hawtio 영역을 추가합니다.<security-domain name="hawtio" cache-type="default"> <authentication> <login-module code="org.keycloak.adapters.jaas.BearerTokenLoginModule" flag="required"> <module-option name="keycloak-config-file" value="${hawtio.keycloakServerConfig}"/> </login-module> </authentication> </security-domain>
<security-domain name="hawtio" cache-type="default"> <authentication> <login-module code="org.keycloak.adapters.jaas.BearerTokenLoginModule" flag="required"> <module-option name="keycloak-config-file" value="${hawtio.keycloakServerConfig}"/> </login-module> </authentication> </security-domain>
Copy to Clipboard Copied! secure-deployment
섹션hawtio
를 어댑터 하위 시스템에 추가합니다. 이렇게 하면 Hawtio WAR에서 JAAS 로그인 모듈 클래스를 찾을 수 있습니다.<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <secure-deployment name="hawtio-wildfly-1.4.0.redhat-630396.war" /> </subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <secure-deployment name="hawtio-wildfly-1.4.0.redhat-630396.war" /> </subsystem>
Copy to Clipboard Copied! Hawtio를 사용하여 JBoss EAP 6.4 서버를 다시 시작하십시오.
cd $EAP_HOME/bin ./standalone.sh -Djboss.socket.binding.port-offset=101
cd $EAP_HOME/bin ./standalone.sh -Djboss.socket.binding.port-offset=101
Copy to Clipboard Copied! - http://localhost:8181/hawtio 에서 Hawtio에 액세스합니다. Red Hat Single Sign-On으로 보호됩니다.
2.1.7. JBoss Fuse 7 어댑터
Red Hat Single Sign-On은 JBoss Fuse 7 에서 실행되는 웹 애플리케이션 보안을 지원합니다.
JBoss Fuse 7은 JBoss Fuse 7.4.0과 기본적으로 동일한 JBoss EAP 7 Adapter 와 동일한 기능을 활용합니다. 이 어댑터는 다양한 종류의 웹 애플리케이션을 실행하는 데 사용됩니다.
지원되는 유일한 버전의 Fuse 7은 최신 버전입니다. 이전 버전의 Fuse 7을 사용하는 경우 일부 기능이 제대로 작동하지 않을 수 있습니다. 특히 7.12.0 미만의 Fuse 7 버전에서는 통합이 작동하지 않습니다.
Fuse에서 다음 항목에 대한 보안이 지원됩니다.
- Pax Web comes Extender를 사용하여 Fuse에 배포된 클래식 WAR 애플리케이션
- Pax Web whiteboard Extender를 사용하여 Fuse에 OSGI 서비스로 배포되고 표준 OSGi Enterprise HTTP Service인 org.osgi.service.http.HttpService#registerServlet()을 통해 등록된 서블릿
- Camel Cryostat 구성 요소로 실행되는 Apache Camel Cryostat 끝점
- 자체적인 Cryostat 엔진에서 실행되는 Apache CXF 끝점
- CXF 서블릿에서 제공하는 기본 엔진에서 실행되는 Apache CXF 끝점
- SSH 및 Cryostat 관리자 액세스
- Hawtio 관리 콘솔
2.1.7.1. Fuse 7 내부의 웹 애플리케이션 보안
먼저 Red Hat Single Sign-On Karaf 기능을 설치해야 합니다. 다음으로 보안하려는 애플리케이션 유형에 따라 단계를 수행해야 합니다. 참조된 모든 웹 애플리케이션에서는 Red Hat Single Sign-On Cryostat 인증 메커니즘을 기본 웹 서버에 삽입해야 합니다. 이를 수행하는 단계는 애플리케이션 유형에 따라 다릅니다. 자세한 내용은 아래에 설명되어 있습니다.
2.1.7.2. Keycloak 기능 설치
먼저 JBoss Fuse 환경에서 keycloak-pax-http-undertow
및 keycloak-jaas
기능을 설치해야 합니다. keycloak-pax-http-undertow
기능에는 Fuse 어댑터 및 모든 타사 종속 항목이 포함되어 있습니다. keycloak-jaas
에는 SSH 및 Cryostat 인증에 사용되는 JAAS 모듈이 포함되어 있습니다. Maven 리포지토리 또는 아카이브에서 설치할 수 있습니다.
2.1.7.2.1. Maven 리포지토리에서 설치
사전 요구 사항
- 온라인 상태여야 하며 Maven 리포지토리에 액세스할 수 있어야 합니다.
- Red Hat Single Sign-On의 경우 아티팩트를 설치할 수 있도록 적절한 Maven 리포지토리를 구성합니다. 자세한 내용은 JBoss Enterprise Maven 리포지토리 페이지를 참조하십시오.
Maven 리포지토리가 https://maven.repository.redhat.com/ga/ 이라고 가정하고
$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg
파일에 다음을 추가하고 지원되는 리포지토리 목록에 리포지토리를 추가합니다. 예를 들면 다음과 같습니다.config:edit org.ops4j.pax.url.mvn config:property-append org.ops4j.pax.url.mvn.repositories ,https://maven.repository.redhat.com/ga/@id=redhat.product.repo config:update feature:repo-refresh
config:edit org.ops4j.pax.url.mvn config:property-append org.ops4j.pax.url.mvn.repositories ,https://maven.repository.redhat.com/ga/@id=redhat.product.repo config:update feature:repo-refresh
Copy to Clipboard Copied!
절차
- Start JBoss Fuse 7.4.0
Karaf 터미널에서 다음을 입력합니다.
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
Copy to Clipboard Copied! 또한 Cryostat 기능을 설치해야 할 수도 있습니다.
feature:install pax-web-http-undertow
feature:install pax-web-http-undertow
Copy to Clipboard Copied! 기능이 설치되었는지 확인합니다.
feature:list | grep keycloak
feature:list | grep keycloak
Copy to Clipboard Copied!
2.1.7.2.2. ZIP 번들에서 설치
이 기능은 오프라인 상태이거나 Maven을 사용하여 JAR 파일 및 기타 아티팩트를 가져오지 않으려는 경우에 유용합니다.
절차
- Sotware 다운로드 사이트에서 Red Hat Single Sign-On Fuse 어댑터 ZIP 아카이브를 다운로드합니다.
JBoss Fuse의 루트 디렉터리에 압축을 풉니다. 그런 다음 종속 항목은
시스템
디렉터리 아래에 설치됩니다. 기존의 모든 files를 덮어쓸 수 있습니다.JBoss Fuse 7.4.0에서 이 기능을 사용하십시오.
cd /path-to-fuse/fuse-karaf-7.z unzip -q /path-to-adapter-zip/rh-sso-7.6.11-fuse-adapter.zip
cd /path-to-fuse/fuse-karaf-7.z unzip -q /path-to-adapter-zip/rh-sso-7.6.11-fuse-adapter.zip
Copy to Clipboard Copied! Fuse를 시작하고 fuse/karaf 터미널에서 다음 명령을 실행합니다.
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
Copy to Clipboard Copied! -
해당 Cryostat 어댑터를 설치합니다. JBoss Fuse
시스템
디렉터리에서 아티팩트를 직접 사용할 수 있으므로 Maven 리포지토리를 사용할 필요가 없습니다.
2.1.7.3. Classic WAR 애플리케이션 보안
절차
/WEB-INF/web.xml
파일에서 필요한 내용을 선언합니다.- <security-constraint> 요소의 보안 제약 조건
-
<login-config> 요소의 로그인 구성입니다. <
auth-method>가
KEYCLOAK
인지 확인합니다. <security-role> 요소의 보안 역할
예를 들면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
Copy to Clipboard Copied!
WAR의
/WEB-INF/
디렉터리에 새 파일 keycloak.json을 생성합니다. 이 구성 파일의 형식은 Java Adapters Config 섹션에 설명되어 있습니다. 외부 어댑터 구성에 설명된 대로 이 파일을 외부에서 사용할 수도 있습니다.예를 들면 다음과 같습니다.
{ "realm": "demo", "resource": "customer-portal", "auth-server-url": "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
{ "realm": "demo", "resource": "customer-portal", "auth-server-url": "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
Copy to Clipboard Copied! - Fuse 6 어댑터와 달리 MANIFEST.MF에는 특별한 OSGi 가져오기가 필요하지 않습니다.
2.1.7.3.1. 구성 확인자
keycloak.json
어댑터 구성 파일은 번들(기본 동작) 또는 파일 시스템의 디렉터리에 저장할 수 있습니다. 구성 파일의 실제 소스를 지정하려면 keycloak.config.resolver
배포 매개변수를 원하는 구성 확인자 클래스로 설정합니다. 예를 들어 클래식 WAR 애플리케이션에서 다음과 같이 web.xml
파일에서 keycloak.config.resolver
컨텍스트 매개변수를 설정합니다.
<context-param> <param-name>keycloak.config.resolver</param-name> <param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value> </context-param>
<context-param>
<param-name>keycloak.config.resolver</param-name>
<param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value>
</context-param>
keycloak.config.resolver
에 대해 다음 해결자를 사용할 수 있습니다.
- org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver
-
이는 기본 확인자입니다. 구성 파일은 보안 중인 OSGi 번들 내부에서 예상됩니다. 기본적으로 이름이
WEB-INF/keycloak.json
이라는 파일을 로드하지만 이 파일 이름은configLocation
속성을 통해 구성할 수 있습니다. - org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver
이 확인자는
keycloak.config
시스템 속성에 지정된 폴더 내에서 <your_web_context>-keycloak.json
이라는 파일을 검색합니다.keycloak.config
를 설정하지 않으면karaf.etc
시스템 속성이 대신 사용됩니다.예를 들어 웹 애플리케이션이 컨텍스트
my-portal
에 배포된 경우 어댑터 구성이${keycloak.config}/my-portal-keycloak.json
파일에서 로드되거나${karaf.etc}/my-portal-keycloak.json
에서 로드됩니다.- org.keycloak.adapters.osgi.HierarchicalPathBasedKeycloakConfigResolver
이 확인자는 위의
PathBasedKeycloakConfigResolver
와 유사합니다. 여기서 지정된 URI 경로의 경우 구성 위치가 가장 구체적인지 확인합니다.예를 들어
/my/web-app/context
URI의 경우 첫 번째 구성 위치가 존재할 때까지 다음 구성 위치가 있는지 검색합니다.-
${karaf.etc}/my-web-app-context-keycloak.json
-
${karaf.etc}/my-web-app-keycloak.json
-
${karaf.etc}/my-keycloak.json
-
${karaf.etc}/keycloak.json
-
2.1.7.4. OSGI 서비스로 배포된 서블릿 보안
기존 WAR 애플리케이션으로 배포되지 않은 OSGI 번들 프로젝트 내부에 서블릿 클래스가 있는 경우 이 방법을 사용할 수 있습니다. Fuse는 Pax Web whiteboard Extender를 사용하여 웹 애플리케이션과 같은 서블릿을 배포합니다.
절차
Red Hat Single Sign-On은 애플리케이션에 대한 인증 방법 및 보안 제약 조건을 구성할 수 있는
org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService
를 제공합니다. 애플리케이션 내부에OSGI-INF/blueprint/blueprint.xml
파일에서 이러한 서비스를 선언해야 합니다. 서블릿은 이에 따라 달라야 합니다. 예제 구성:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="servletConstraintMapping" class="org.keycloak.adapters.osgi.PaxWebSecurityConstraintMapping"> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authentication" value="true"/> <property name="url" value="/product-portal/*"/> </bean> <!-- This handles the integration and setting the login-config and security-constraints parameters --> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration" /> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="servletConstraintMapping" class="org.keycloak.adapters.osgi.PaxWebSecurityConstraintMapping"> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authentication" value="true"/> <property name="url" value="/product-portal/*"/> </bean> <!-- This handles the integration and setting the login-config and security-constraints parameters --> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration" /> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
Copy to Clipboard Copied! 프로젝트 내부에
WEB-INF
디렉토리를 사용하고(프로젝트가 웹 애플리케이션이 아니더라도) Classic WAR 애플리케이션 섹션에 설명된 대로/gateway-INF/keycloak.json
파일을 생성해야 할 수도 있습니다. security-constraints가 블루프린트 구성 파일에 선언되므로web.xml
파일이 필요하지 않습니다.- Fuse 6 어댑터와 달리 MANIFEST.MF에는 특별한 OSGi 가져오기가 필요하지 않습니다.
2.1.7.5. Apache Camel 애플리케이션 보안
블루프린트를 통해 적절한 보안 제약 조건을 삽입하고 사용된 구성 요소를 undertow-keycloak
로 업데이트하여 camel-undertow 구성 요소로 구현된 Apache Camel 엔드포인트를 보호할 수 있습니다. 다음과 같은 구성으로 Camel 애플리케이션에 OSGI-INF/blueprint/blueprint.xml
파일을 추가해야 합니다. 역할, 보안 제약 조건 매핑 및 어댑터 구성은 환경과 필요에 따라 약간 다를 수 있습니다.
표준 undertow
구성 요소와 비교하여 undertow-keycloak
구성 요소는 두 가지 새 속성을 추가합니다.
-
configResolver
는 Red Hat Single Sign-On 어댑터 구성을 제공하는 해결자 blank입니다. 사용 가능한 해결 방법은 Configuration Resolvers 섹션에 나열되어 있습니다. -
allowedRoles
는 쉼표로 구분된 역할 목록입니다. 서비스에 액세스하는 사용자는 액세스를 허용하려면 하나 이상의 역할이 있어야 합니다.
예를 들면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/blueprint" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint-2.17.1.xsd"> <bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" > <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" /> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route id="httpBridge"> <from uri="undertow-keycloak:http://0.0.0.0:8383/admin-camel-endpoint?matchOnUriPrefix=true&configResolver=#keycloakConfigResolver&allowedRoles=admin" /> <process ref="helloProcessor" /> <log message="The message from camel endpoint contains ${body}"/> </route> </camelContext> </blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint-2.17.1.xsd">
<bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" >
<property name="bundleContext" ref="blueprintBundleContext" />
</bean>
<bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" />
<camelContext id="blueprintContext"
trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<route id="httpBridge">
<from uri="undertow-keycloak:http://0.0.0.0:8383/admin-camel-endpoint?matchOnUriPrefix=true&configResolver=#keycloakConfigResolver&allowedRoles=admin" />
<process ref="helloProcessor" />
<log message="The message from camel endpoint contains ${body}"/>
</route>
</camelContext>
</blueprint>
-
META-INF/MANIFEST의
에는 다음 가져오기가 포함되어야 합니다.Import-Package
.MF
javax.servlet;version="[3,4)", javax.servlet.http;version="[3,4)", javax.net.ssl, org.apache.camel.*, org.apache.camel;version="[2.13,3)", io.undertow.*, org.keycloak.*;version="18.0.18.redhat-00001", org.osgi.service.blueprint, org.osgi.service.blueprint.container
javax.servlet;version="[3,4)",
javax.servlet.http;version="[3,4)",
javax.net.ssl,
org.apache.camel.*,
org.apache.camel;version="[2.13,3)",
io.undertow.*,
org.keycloak.*;version="18.0.18.redhat-00001",
org.osgi.service.blueprint,
org.osgi.service.blueprint.container
2.1.7.6. Camel RestDSL
Camel RestDSL은 유창한 방식으로 REST 엔드포인트를 정의하는 데 사용되는 Camel 기능입니다. 그러나 특정 구현 클래스를 계속 사용하고 Red Hat Single Sign-On과 통합하는 방법에 대한 지침을 제공해야 합니다.
통합 메커니즘을 구성하는 방법은 RestDSL 정의 경로를 구성하는 Camel 구성 요소에 따라 다릅니다.
다음 예제에서는 undertow-keycloak
구성 요소를 사용하여 통합을 구성하는 방법과 이전 블루프린트 예제에 정의된 일부 빈에 대한 참조를 보여줍니다.
<camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <!--the link with Keycloak security handlers happens by using undertow-keycloak component --> <restConfiguration apiComponent="undertow-keycloak" contextPath="/restdsl" port="8484"> <endpointProperty key="configResolver" value="#keycloakConfigResolver" /> <endpointProperty key="allowedRoles" value="admin,superadmin" /> </restConfiguration> <rest path="/hello" > <description>Hello rest service</description> <get uri="/{id}" outType="java.lang.String"> <description>Just a hello</description> <to uri="direct:justDirect" /> </get> </rest> <route id="justDirect"> <from uri="direct:justDirect"/> <process ref="helloProcessor" /> <log message="RestDSL correctly invoked ${body}"/> <setBody> <constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant> </setBody> </route> </camelContext>
<camelContext id="blueprintContext"
trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<!--the link with Keycloak security handlers happens by using undertow-keycloak component -->
<restConfiguration apiComponent="undertow-keycloak" contextPath="/restdsl" port="8484">
<endpointProperty key="configResolver" value="#keycloakConfigResolver" />
<endpointProperty key="allowedRoles" value="admin,superadmin" />
</restConfiguration>
<rest path="/hello" >
<description>Hello rest service</description>
<get uri="/{id}" outType="java.lang.String">
<description>Just a hello</description>
<to uri="direct:justDirect" />
</get>
</rest>
<route id="justDirect">
<from uri="direct:justDirect"/>
<process ref="helloProcessor" />
<log message="RestDSL correctly invoked ${body}"/>
<setBody>
<constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant>
</setBody>
</route>
</camelContext>
2.1.7.7. 별도의 Cryostat 엔진에서 Apache CXF 끝점 보안
별도의 Cryostat 엔진에서 Red Hat Single Sign-On에서 보안한 CXF 엔드포인트를 실행하려면 다음 절차를 수행합니다.
절차
OSGI-INF/blueprint/blueprint.xml
을 애플리케이션에 추가하고, 이 경우 Camel 구성과 유사하게 적절한 구성 확인자 빈을 추가합니다.httpu:engine-factory
에서org.keycloak.adapters.osgi.undertow.CxfKeycloakAuthHandler
처리기를 해당 camel 구성을 사용하여 선언합니다. CFX Cryostat-WS 애플리케이션의 구성은 다음과 유사할 수 있습니다.<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://cxf.apache.org/blueprint/core" xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration". xsi:schemaLocation=" http://cxf.apache.org/transports/http-undertow/configuration http://cxf.apache.org/schemas/configuration/http-undertow.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd"> <bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" > <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <httpu:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpu:engine port="8282"> <httpu:handlers> <bean class="org.keycloak.adapters.osgi.undertow.CxfKeycloakAuthHandler"> <property name="configResolver" ref="keycloakConfigResolver" /> </bean> </httpu:handlers> </httpu:engine> </httpu:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint"/> </blueprint>
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://cxf.apache.org/blueprint/core" xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration". xsi:schemaLocation=" http://cxf.apache.org/transports/http-undertow/configuration http://cxf.apache.org/schemas/configuration/http-undertow.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd"> <bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" > <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <httpu:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpu:engine port="8282"> <httpu:handlers> <bean class="org.keycloak.adapters.osgi.undertow.CxfKeycloakAuthHandler"> <property name="configResolver" ref="keycloakConfigResolver" /> </bean> </httpu:handlers> </httpu:engine> </httpu:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint"/> </blueprint>
Copy to Clipboard Copied! CXF Cryostat-RS 애플리케이션의 경우 engine-factory에 따라 끝점의 구성에 차이가 있을 수 있습니다.
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
Copy to Clipboard Copied! -
META-INF/MANIFEST.MF
의Import-Package
에는 이러한 가져오기가 포함되어야 합니다.
META-INF.cxf;version="[2.7,3.3)", META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional, org.apache.cxf.bus;version="[2.7,3.3)", org.apache.cxf.bus.spring;version="[2.7,3.3)", org.apache.cxf.bus.resource;version="[2.7,3.3)", org.apache.cxf.transport.http;version="[2.7,3.3)", org.apache.cxf.*;version="[2.7,3.3)", org.springframework.beans.factory.config, org.keycloak.*;version="18.0.18.redhat-00001"
META-INF.cxf;version="[2.7,3.3)",
META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional,
org.apache.cxf.bus;version="[2.7,3.3)",
org.apache.cxf.bus.spring;version="[2.7,3.3)",
org.apache.cxf.bus.resource;version="[2.7,3.3)",
org.apache.cxf.transport.http;version="[2.7,3.3)",
org.apache.cxf.*;version="[2.7,3.3)",
org.springframework.beans.factory.config,
org.keycloak.*;version="18.0.18.redhat-00001"
2.1.7.8. 기본 Cryostat 엔진에서 Apache CXF 끝점 보안
일부 서비스는 시작 시 배포된 서블릿과 함께 자동으로 제공됩니다. 이러한 서비스 중 하나는 http://localhost:8181/cxf 컨텍스트에서 실행되는 CXF 서블릿입니다. Fuse의 Pax Web은 구성 관리자를 통해 기존 컨텍스트 변경을 지원합니다. 이는 Red Hat Single Sign-On의 엔드포인트를 보호하는 데 사용할 수 있습니다.
애플리케이션 내의 구성 파일 OSGI-INF/blueprint/blueprint.xml
은 아래 파일과 유사할 수 있습니다. 애플리케이션 관련 엔드포인트인 Cryostat-RS customerservice
엔드포인트를 추가합니다.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> <!-- JAXRS Application --> <bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" /> <jaxrs:server id="cxfJaxrsServer" address="/customerservice"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> <jaxrs:serviceBeans> <ref component-id="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> </blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd">
<!-- JAXRS Application -->
<bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" />
<jaxrs:server id="cxfJaxrsServer" address="/customerservice">
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</jaxrs:providers>
<jaxrs:serviceBeans>
<ref component-id="customerBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
</blueprint>
또한 ${karaf.etc}/org.ops4j.pax.web.context-anyName.cfg 파일을
생성해야 합니다. pax-web-runtime
번들에 의해 추적되는 팩토리 PID 구성으로 처리됩니다. 이러한 구성에는 표준 web.xml
의 일부 속성에 해당하는 다음 속성이 포함될 수 있습니다.
bundle.symbolicName = org.apache.cxf.cxf-rt-transports-http context.id = default context.param.keycloak.config.resolver = org.keycloak.adapters.osgi.HierarchicalPathBasedKeycloakConfigResolver login.config.authMethod = KEYCLOAK security.cxf.url = /cxf/customerservice/* security.cxf.roles = admin, user
bundle.symbolicName = org.apache.cxf.cxf-rt-transports-http
context.id = default
context.param.keycloak.config.resolver = org.keycloak.adapters.osgi.HierarchicalPathBasedKeycloakConfigResolver
login.config.authMethod = KEYCLOAK
security.cxf.url = /cxf/customerservice/*
security.cxf.roles = admin, user
구성 관리자 파일에서 사용 가능한 속성에 대한 자세한 내용은 Fuse 설명서를 참조하십시오. 위의 속성에는 다음과 같은 의미가 있습니다.
bundle.symbolicName
andcontext.id
-
org.ops4j.pax.web.service.WebContainer
내의 번들 및 배포 컨텍스트 식별. context.param.keycloak.config.resolver
-
클래식 WAR의
web.xml
과 동일하게 번들에keycloak.config.resolver
의 값을 제공합니다. 사용 가능한 해결 방법은 구성 해결 방법 섹션에 설명되어 있습니다. login.config.authMethod
-
인증 방법.
KEYCLOAK
여야 합니다. 보안.anyName.url
및security.anyName.roles
개별 보안 제약 조건의 속성 값은 각각
web.xml
의security-constraint/web-resource-collection/url-pattern
및security-constraint/auth-constraint/role-name
에 설정된 것처럼 설정합니다. 역할은 쉼표로 구분되고 주위에 공백을 사용합니다.anyName
식별자는 임의의 식별자일 수 있지만 동일한 보안 제약 조건의 개별 속성에 대해 일치해야 합니다.참고일부 Fuse 버전에는 역할이
", "
(콤마 및 단일 공간)로 구분되어야 하는 버그가 포함되어 있습니다. 역할을 분리하기 위해 정확히 이 표기법을 사용해야 합니다.
META-INF/MANIFEST.MF
의 Import-Package
에는 최소한 다음 가져오기가 포함되어야 합니다.
javax.ws.rs;version="[2,3)", META-INF.cxf;version="[2.7,3.3)", META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional, org.apache.cxf.transport.http;version="[2.7,3.3)", org.apache.cxf.*;version="[2.7,3.3)", com.fasterxml.jackson.jaxrs.json;version="${jackson.version}"
javax.ws.rs;version="[2,3)",
META-INF.cxf;version="[2.7,3.3)",
META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional,
org.apache.cxf.transport.http;version="[2.7,3.3)",
org.apache.cxf.*;version="[2.7,3.3)",
com.fasterxml.jackson.jaxrs.json;version="${jackson.version}"
2.1.7.9. Fuse 관리 서비스 보안
2.1.7.9.1. SSH 인증으로 Fuse 터미널 사용
Red Hat Single Sign-On은 주로 웹 애플리케이션의 인증에 대한 사용 사례를 다루지만 다른 웹 서비스 및 애플리케이션이 Red Hat Single Sign-On으로 보호되는 경우 Red Hat Single Sign-On 인증 정보를 사용한 SSH와 같은 비 웹 관리 서비스를 보호하는 것이 가장 좋습니다. Red Hat Single Sign-On에 대한 원격 연결을 허용하고 리소스 소유자 암호 자격 증명을 기반으로 인증 정보를 확인하는 JAAS 로그인 모듈을 사용하여 이 작업을 수행할 수 있습니다.
SSH 인증을 활성화하려면 다음 절차를 수행합니다.
절차
-
Red Hat Single Sign-On에서 SSH 인증에 사용할 클라이언트(예:
ssh-jmx-admin-client
)를 만듭니다. 이 클라이언트에는직접 액세스 권한 부여가 설정되어
있어야 합니다. $FUSE_HOME/etc/org.apache.karaf.shell.cfg
파일에서 이 속성을 업데이트하거나 지정합니다.sshRealm=keycloak
sshRealm=keycloak
Copy to Clipboard Copied! 환경 및 Red Hat Single Sign-On 클라이언트 설정에 따라 다음과 유사한 콘텐츠를 사용하여
$FUSE_HOME/etc/keycloak-direct-access.json
파일을 추가합니다.{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
Copy to Clipboard Copied! 이 파일은 SSH 인증을 위해
keycloak
JAAS 영역의 JAAS DirectAccessGrantsLoginModule에서 사용하는 클라이언트 애플리케이션 구성을 지정합니다.Fuse를 시작하고
keycloak
JAAS 영역을 설치합니다. 가장 쉬운 방법은 JAAS 영역이 사전 정의된keycloak-jaas
기능을 설치하는 것입니다. 순위가 높은 자체keycloak
JAAS 영역을 사용하여 기능의 사전 정의된 영역을 재정의할 수 있습니다. 자세한 내용은 JBoss Fuse 설명서 를 참조하십시오.Fuse 터미널에서 다음 명령을 사용하십시오.
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak-jaas
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.18.redhat-00001/xml/features features:install keycloak-jaas
Copy to Clipboard Copied! 터미널에 다음을 입력하여 SSH를
admin
사용자로 사용하여 로그인합니다.ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
Copy to Clipboard Copied! -
암호 를 사용하여
로그인합니다
.
일부 이후 운영 체제에서는 SSH 명령의 -o 옵션 -o HostKeyAlgorithms=+ssh-dss
를 사용해야 할 수도 있습니다. 이후 SSH 클라이언트는 기본적으로 ssh-dss
알고리즘 사용을 허용하지 않기 때문입니다. 그러나 기본적으로 현재 JBoss Fuse 7.4.0에서 사용됩니다.
사용자에게 모든 작업을 수행하거나 작업 하위 집합을 수행하려면 영역 역할 admin
이 있어야 합니다(예: 사용자가 읽기 전용 Karaf 명령만 실행하도록 제한하는 뷰어 역할). 사용 가능한 역할은 $FUSE_HOME/etc/org.apache.karaf.shell.cfg
또는 $FUSE_HOME/etc/system.properties
에서 구성됩니다.
2.1.7.9.2. Cryostat 인증 사용
jconsole 또는 다른 외부 툴을 사용하여 RMI를 통해 remotely에 연결하려는 경우 Cryostat 인증이 필요할 수 있습니다. 그렇지 않으면 jolokia 에이전트가 기본적으로 hawt.io에 설치되므로 hawt.io/jolokia를 사용하는 것이 더 좋습니다. 자세한 내용은 Hawtio 관리 콘솔을 참조하십시오.
Cryostat 인증을 사용하려면 다음 절차를 수행합니다.
절차
$FUSE_HOME/etc/org.apache.karaf.management.cfg
파일에서 jmxRealm 속성을 다음과 같이 변경합니다.jmxRealm=keycloak
jmxRealm=keycloak
Copy to Clipboard Copied! -
위의 SSH 섹션에 설명된 대로
keycloak-jaas
기능을 설치하고$FUSE_HOME/etc/keycloak-direct-access.json
파일을 구성합니다. - jconsole에서는 다음과 같은 URL을 사용할 수 있습니다.
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
및 인증 정보: admin/password(사용자 환경에 따라 관리자 권한이 있는 사용자 기반).
2.1.7.10. Hawtio 관리 콘솔 보안
Red Hat Single Sign-On을 사용하여 Hawtio 관리 콘솔을 보호하려면 다음 절차를 수행합니다.
절차
-
해당 영역의 Red Hat Single Sign-On 관리 콘솔에서 클라이언트를 생성합니다. 예를 들어 Red Hat Single Sign-On
데모
영역에서 클라이언트hawtio-client
를 생성하고, 액세스 유형으로public
을 지정하고, Hawtio: http://localhost:8181/hawtio/*를 가리키는 리디렉션 URI를 지정합니다. 해당 웹 출처를 구성합니다(이 경우 http://localhost:8181).hawtio-client
클라이언트 세부 정보의 범위 탭에 계정 클라이언트의 view-profile 클라이언트 역할을 포함하도록 클라이언트 범위 매핑을 설정합니다. 아래 예제와 유사한 내용을 사용하여
$FUSE_HOME/etc
디렉터리에keycloak-hawtio-client.json
파일을 생성합니다. Red Hat Single Sign-On 환경에 따라 ,리소스
,auth-server-url
속성을 변경합니다.resource
속성은 이전 단계에서 생성한 클라이언트를 가리켜야 합니다. 이 파일은 클라이언트(Hawtio JavaScript 애플리케이션) 측에서 사용합니다.{ "realm" : "demo", "clientId" : "hawtio-client", "url" : "http://localhost:8080/auth", "ssl-required" : "external", "public-client" : true }
{ "realm" : "demo", "clientId" : "hawtio-client", "url" : "http://localhost:8080/auth", "ssl-required" : "external", "public-client" : true }
Copy to Clipboard Copied! 아래 예제와 유사한 콘텐츠를 사용하여
$FUSE_HOME/etc
디렉터리에keycloak-direct-access.json
파일을 생성합니다. Red Hat Single Sign-On 환경에 따라realm
및url
속성을 변경합니다. 이 파일은 JavaScript 클라이언트에서 사용합니다.{ "realm" : "demo", "resource" : "ssh-jmx-admin-client", "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
{ "realm" : "demo", "resource" : "ssh-jmx-admin-client", "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
Copy to Clipboard Copied! 아래 예제와 유사한 내용을 사용하여
$FUSE_HOME/etc
dicrectory에keycloak-hawtio.json
파일을 생성합니다. Red Hat Single Sign-On 환경에 따라realm
및auth-server-url
속성을 변경합니다. 이 파일은 서버의 어댑터 (JAAS 로그인 모듈) 측에서 사용됩니다.{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
Copy to Clipboard Copied! JBoss Fuse 7.4.0 을 시작하고 Keycloak 기능을 설치합니다. 그런 다음 Karaf 터미널을 입력합니다.
system:property -p hawtio.keycloakEnabled true system:property -p hawtio.realm keycloak system:property -p hawtio.keycloakClientConfig file://\${karaf.base}/etc/keycloak-hawtio-client.json system:property -p hawtio.rolePrincipalClasses org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal restart io.hawt.hawtio-war
system:property -p hawtio.keycloakEnabled true system:property -p hawtio.realm keycloak system:property -p hawtio.keycloakClientConfig file://\${karaf.base}/etc/keycloak-hawtio-client.json system:property -p hawtio.rolePrincipalClasses org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal restart io.hawt.hawtio-war
Copy to Clipboard Copied! http://localhost:8181/hawtio 으로 이동하여 Red Hat Single Sign-On 영역에서 사용자로 로그인합니다.
사용자가 Hawtio에 성공적으로 인증하려면 적절한 realm 역할이 있어야 합니다. 사용 가능한 역할은
hawtio.roles
의$FUSE_HOME/etc/system.properties
파일에서 구성됩니다.
2.1.8. Spring Boot 어댑터
Spring Boot Adapter는 더 이상 사용되지 않으며 RH-SSO의 8.0 이상 버전에 포함되어 있지 않습니다. 이 어댑터는 RH-SSO 7.x의 라이프사이클 동안 유지됩니다. Spring Boot 애플리케이션을 RH-SSO와 통합하려면 Spring Security로 마이그레이션해야 합니다.
2.1.8.1. Spring Boot 어댑터 설치
Spring Boot 앱을 보호하려면 앱에 Keycloak Spring Boot 어댑터 JAR을 추가해야 합니다. 그런 다음 일반 Spring Boot 구성 (application.properties
)을 통해 추가 구성을 제공해야 합니다.
Keycloak Spring Boot 어댑터는 Spring Boot의 자동 구성을 사용하므로 이 어댑터 Keycloak Spring Boot Starter를 프로젝트에 추가하는 것입니다.
절차
Maven을 사용하여 프로젝트에 Starter를 추가하려면 종속 항목에 다음을 추가합니다.
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> </dependency>
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> </dependency>
Copy to Clipboard Copied! 어댑터 BOM 종속성을 추가합니다.
<dependencyManagement> <dependencies> <dependency> <groupId>org.keycloak.bom</groupId> <artifactId>keycloak-adapter-bom</artifactId> <version>18.0.18.redhat-00001</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependencyManagement> <dependencies> <dependency> <groupId>org.keycloak.bom</groupId> <artifactId>keycloak-adapter-bom</artifactId> <version>18.0.18.redhat-00001</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Copy to Clipboard Copied!
현재 다음 포함 컨테이너는 지원되며 Starter를 사용하는 경우 추가 종속 항목이 필요하지 않습니다.
- Tomcat
- CloudEvent
- allty
2.1.8.2. Spring Boot 어댑터 구성
Red Hat Single Sign-On을 사용하도록 Spring Boot 앱을 구성하려면 절차를 사용하십시오.
절차
keycloak.json
파일 대신 일반 Spring Boot 구성을 통해 Spring Boot 어댑터의 영역을 구성합니다. 예를 들면 다음과 같습니다.keycloak.realm = demorealm keycloak.auth-server-url = http://127.0.0.1:8080/auth keycloak.ssl-required = external keycloak.resource = demoapp keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111 keycloak.use-resource-role-mappings = true
keycloak.realm = demorealm keycloak.auth-server-url = http://127.0.0.1:8080/auth keycloak.ssl-required = external keycloak.resource = demoapp keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111 keycloak.use-resource-role-mappings = true
Copy to Clipboard Copied! keycloak Spring Boot Adapter (예: 테스트에서)
keycloak.enabled = false
를 설정하여 비활성화할 수 있습니다.-
keycloak.json과 달리 Policy Enforcer를 구성하려면
policy-enforcer-config
대신policy-enforcer
-config를 사용합니다. 일반적으로
web.xml
에 들어갈 자karta EE 보안 구성을 지정합니다.Spring Boot Adapter는
로그인 방법을
KEYCLOAK
로 설정하고 시작 시security-constraints
를 구성합니다. 다음은 구성의 예입니다.keycloak.securityConstraints[0].authRoles[0] = admin keycloak.securityConstraints[0].authRoles[1] = user keycloak.securityConstraints[0].securityCollections[0].name = insecure stuff keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /insecure keycloak.securityConstraints[1].authRoles[0] = admin keycloak.securityConstraints[1].securityCollections[0].name = admin stuff keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
keycloak.securityConstraints[0].authRoles[0] = admin keycloak.securityConstraints[0].authRoles[1] = user keycloak.securityConstraints[0].securityCollections[0].name = insecure stuff keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /insecure keycloak.securityConstraints[1].authRoles[0] = admin keycloak.securityConstraints[1].securityCollections[0].name = admin stuff keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
Copy to Clipboard Copied!
Spring Application을 WAR로 배포하려는 경우 Spring Boot Adapter를 사용하지 말고 사용 중인 애플리케이션 서버 또는 서블릿 컨테이너에 전용 어댑터를 사용해야 합니다. Spring Boot에는 web.xml
파일도 포함되어 있어야 합니다.
2.1.9. Java 서블릿 필터 어댑터
Red Hat Single Sign-On 어댑터가 없는 플랫폼에 Java Servlet 애플리케이션을 배포하는 경우 서블릿 필터 어댑터를 사용하기로 선택합니다. 이 어댑터는 다른 어댑터와 약간 다르게 작동합니다. web.xml에서 보안 제약 조건을 정의하지 않습니다. 대신 Red Hat Single Sign-On 서블릿 필터 어댑터를 사용하여 필터 매핑을 정의하여 보안하려는 URL 패턴을 보호합니다.
Backchannel logout은 표준 어댑터와 약간 다르게 작동합니다. HTTP 세션을 무효화하는 대신 세션 ID를 로그아웃한 것으로 표시합니다. 세션 ID를 기반으로 HTTP 세션을 무효화하는 표준 방법은 없습니다.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>application</module-name> <filter> <filter-name>Keycloak Filter</filter-name> <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class> </filter> <filter-mapping> <filter-name>Keycloak Filter</filter-name> <url-pattern>/keycloak/*</url-pattern> <url-pattern>/protected/*</url-pattern> </filter-mapping> </web-app>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>application</module-name>
<filter>
<filter-name>Keycloak Filter</filter-name>
<filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Keycloak Filter</filter-name>
<url-pattern>/keycloak/*</url-pattern>
<url-pattern>/protected/*</url-pattern>
</filter-mapping>
</web-app>
위의 코드 조각에는 두 개의 url-패턴이 있습니다. /protected/* 는 보호하려는 파일이며 /keycloak/* url-pattern은 Red Hat Single Sign-On 서버의 콜백을 처리합니다.
구성된 url-patterns
아래의 일부 경로를 제외해야 하는 경우 Filter init-param keycloak.config.skipPattern
을 사용하여 keycloak 필터가 filter-chain에 즉시 위임해야 하는 경로-패턴을 설명하는 정규식을 구성할 수 있습니다. 기본적으로 skipPattern이 구성되지 않습니다.
패턴은 컨텍스트 경로
없이 requestURI
와 일치합니다. context-path /myapp
에 /myapp/index.html
에 대한 요청이 건너뛰기 패턴에 대해 /index.html
과 일치합니다.
<init-param> <param-name>keycloak.config.skipPattern</param-name> <param-value>^/(path1|path2|path3).*</param-value> </init-param>
<init-param>
<param-name>keycloak.config.skipPattern</param-name>
<param-value>^/(path1|path2|path3).*</param-value>
</init-param>
필터의 url-pattern에서 적용되는 보안 섹션을 가리키는 관리자 URL을 사용하여 Red Hat Single Sign-On 관리 콘솔에서 클라이언트를 구성해야 합니다.
Admin URL은 Admin URL로 콜백을 만들어 백채널 로그아웃과 같은 작업을 수행합니다. 따라서 이 예제의 관리자 URL은 http[s]://hostname/{context-root}/keycloak
이어야 합니다.
세션 ID 매퍼를 사용자 지정해야 하는 경우 Filter init-param keycloak.config.idMapper에서 정규화된 클래스 이름을 구성할 수 있습니다. 세션 ID 매퍼는 사용자 ID 및 세션 ID를 매핑하는 데 사용되는 매퍼입니다. 기본적으로 org.keycloak.adapters.spi.InMemorySessionIdMapper가 구성됩니다.
<init-param> <param-name>keycloak.config.idMapper</param-name> <param-value>org.keycloak.adapters.spi.InMemorySessionIdMapper</param-value> </init-param>
<init-param>
<param-name>keycloak.config.idMapper</param-name>
<param-value>org.keycloak.adapters.spi.InMemorySessionIdMapper</param-value>
</init-param>
Red Hat Single Sign-On 필터는 다른 어댑터와 동일한 구성 매개 변수를 컨텍스트 매개변수 대신 filter init params로 정의해야 합니다.
이 필터를 사용하려면 다음 maven 아티팩트를 WAR poms에 포함합니다.
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-servlet-filter-adapter</artifactId> <version>18.0.18.redhat-00001</version> </dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-servlet-filter-adapter</artifactId>
<version>18.0.18.redhat-00001</version>
</dependency>
2.1.10. 보안 컨텍스트
토큰에 직접 액세스해야 하는 경우 KeycloakSecurityContext
인터페이스를 사용할 수 있습니다. 이 기능은 토큰(예: 사용자 프로필 정보)에서 추가 세부 정보를 검색하거나 Red Hat Single Sign-On에 의해 보호되는 RESTful 서비스를 호출하려는 경우에 유용할 수 있습니다.
서블릿 환경에서는 보안 호출에서 10.0.0.1ServletRequest의 속성으로 사용할 수 있습니다.
httpServletRequest .getAttribute(KeycloakSecurityContext.class.getName());
httpServletRequest
.getAttribute(KeycloakSecurityContext.class.getName());
또는 insecured 요청에서 사용할 수 있습니다.
httpServletRequest.getSession() .getAttribute(KeycloakSecurityContext.class.getName());
httpServletRequest.getSession()
.getAttribute(KeycloakSecurityContext.class.getName());
2.1.11. 오류 처리
Red Hat Single Sign-On에는 서블릿 기반 클라이언트 어댑터의 일부 오류 처리 기능이 있습니다. 인증에 오류가 발생하면 Red Hat Single Sign-On을 통해 10.0.0.1 ServletResponse.sendError()
. web.xml
파일 내에 오류 페이지를 설정하여 원하는 오류를 처리할 수 있습니다. Red Hat Single Sign-On을 사용하면 400, 401, 403 및 500 오류가 발생할 수 있습니다.
<error-page> <error-code>403</error-code> <location>/ErrorHandler</location> </error-page>
<error-page>
<error-code>403</error-code>
<location>/ErrorHandler</location>
</error-page>
Red Hat Single Sign-On은 검색할 수 있는 10.0.0.1ServletRequest
속성도 설정합니다. 특성 이름은 org.keycloak.adapters.spi.AuthenticationError
로, org.keycloak.adapters.OIDCAuthenticationError
로 캐스팅되어야 합니다.
예를 들면 다음과 같습니다.
import org.keycloak.adapters.OIDCAuthenticationError; import org.keycloak.adapters.OIDCAuthenticationError.Reason; ... OIDCAuthenticationError error = (OIDCAuthenticationError) httpServletRequest .getAttribute('org.keycloak.adapters.spi.AuthenticationError'); Reason reason = error.getReason(); System.out.println(reason.name());
import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.adapters.OIDCAuthenticationError.Reason;
...
OIDCAuthenticationError error = (OIDCAuthenticationError) httpServletRequest
.getAttribute('org.keycloak.adapters.spi.AuthenticationError');
Reason reason = error.getReason();
System.out.println(reason.name());
2.1.12. logout
웹 애플리케이션에서 여러 가지 방법으로 로그아웃할 수 있습니다. Jakarta EE 서블릿 컨테이너의 경우>-< ServletRequest.logout()
을 호출할 수 있습니다. 다른 브라우저 애플리케이션의 경우 브라우저를 http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout
로 리디렉션할 수 있으며, 이는 해당 사용자에게 브라우저와 SSO 세션이 있는 경우 사용자를 기록합니다. 사용자가 로그아웃을 확인한 후 실제 로그아웃이 수행됩니다. OpenID Connect RP-Initiated Logout 에 설명된 대로 id_token_hint
,post_logout_redirect_uri
,client_id
등의 매개변수를 선택적으로 포함할 수 있습니다. 따라서 id_token_hint
매개변수를 포함하는 경우 해당 logout을 사용자가 명시적으로 확인할 필요가 없습니다. 로그아웃 후 사용자는 제공되는 경우 지정된 post_logout_redirect_uri
로 자동으로 리디렉션됩니다. post_logout_redirect_uri
가 포함된 경우 client_id
또는 id_token_hint
매개변수를 포함해야 합니다.
로그아웃 프로세스의 일부로 외부 ID 공급자에서 로그아웃하지 않으려면 해당 ID 공급자의 ID(alias)가 값인 시작_idp
매개 변수를 제공할 수 있습니다. 이 매개변수는 logout 끝점이 외부 ID 공급자에 의해 시작된 단일 로그 아웃의 일부로 호출될 때 유용합니다. 시작_idp
매개변수는 RP-Initiated Logout 사양에 설명된 매개변수 외에 Red Hat Single Sign-On 로그 아웃 끝점에서 지원되는 매개변수입니다.
>-< ServletRequest.logout()
옵션을 사용하는 경우 어댑터는 새로 고침 토큰을 전달하는 Red Hat Single Sign-On 서버에 대해 백 채널 POST 호출을 실행합니다. 보호되지 않은 페이지(유효한 토큰을 확인하지 않는 페이지)에서 메서드가 실행되는 경우 새로 고침 토큰을 사용할 수 없으며, 이 경우 어댑터에서 호출을 건너뜁니다. 따라서 보호 페이지를 사용하여>-< ServletRequest.logout()
을 실행하는 것이 좋습니다. 따라서 현재 토큰이 항상 고려되고 Red Hat Single Sign-On 서버와의 상호 작용이 필요한 경우 수행됩니다.
2.1.13. 매개변수 전달
Red Hat Single Sign-On 초기 권한 부여 끝점 요청은 다양한 매개 변수를 지원합니다. 대부분의 매개변수는 OIDC 사양에 설명되어 있습니다. 일부 매개변수는 어댑터 구성에 따라 어댑터에 의해 자동으로 추가됩니다. 그러나 취소 기준으로 추가할 수 있는 몇 가지 매개변수도 있습니다. 보안 애플리케이션 URI를 열면 특정 매개변수가 Red Hat Single Sign-On 권한 부여 엔드포인트로 전달됩니다.
예를 들어 오프라인 토큰을 요청하는 경우 다음과 같은 scope
매개변수로 보안 애플리케이션 URI를 열 수 있습니다.
http://myappserver/mysecuredapp?scope=offline_access
http://myappserver/mysecuredapp?scope=offline_access
매개 변수 scope=offline_access
는 Red Hat Single Sign-On 권한 부여 엔드포인트에 자동으로 전달됩니다.
지원되는 매개변수는 다음과 같습니다.
-
범위 - 공백으로 구분된 범위 목록을 사용합니다. 공백으로 구분된 목록은 일반적으로 특정 클라이언트에 정의된 클라이언트 범위를 참조합니다. 범위
openid
는 항상 어댑터의 범위 목록에 추가됩니다. 예를 들어 범위 옵션주소 전화
번호를 입력하면 Red Hat Single Sign-On에 범위 매개 변수scope=openid 주소 전화가
포함됩니다. 프롬프트 - Red Hat Single Sign-On에서는 다음 설정을 지원합니다.
-
login
- SSO는 무시되고 사용자가 이미 인증된 경우에도 Red Hat Single Sign-On 로그인 페이지가 항상 표시됩니다. -
동의 - 동의
가필요한 고객에게만 적용됩니다
. 이를 사용하는 경우 사용자가 이전에 이 클라이언트에 동의한 경우에도 Consent 페이지가 항상 표시됩니다. -
none
- 로그인 페이지가 표시되지 않습니다. 대신 사용자가 애플리케이션으로 리디렉션되며 사용자가 아직 인증되지 않은 경우 오류가 발생합니다. 이 설정을 사용하면 애플리케이션 측에서 필터/방문기를 생성하고 사용자에게 사용자 정의 오류 페이지를 표시할 수 있습니다. 자세한 내용은 사양을 참조하십시오.
-
-
max_age - 사용자가 이미 인증된 경우에만 사용됩니다. 사용자가 인증할 때부터 측정하여 인증이 지속되도록 허용되는 최대 시간을 지정합니다. user가
maxAge
보다 오래 인증되면 SSO가 무시되고 다시 인증해야 합니다. - login_hint - 로그인 양식에 사용자 이름/이메일 필드를 미리 채우는 데 사용됩니다.
- kc_idp_hint - Red Hat Single Sign-On에 로그인 페이지를 건너뛰고 지정된 ID 공급자로 자동 리디렉션하도록 하는 데 사용됩니다. ID 공급자 설명서에서 추가 정보 .
대부분의 매개변수는 OIDC 사양에 설명되어 있습니다. 유일한 예외는 Red Hat Single Sign-On과 관련된 kc_idp_hint
매개 변수이며 자동으로 사용할 ID 공급자의 이름을 포함합니다. 자세한 내용은 Server Administration Guide 의 Identity Brokering
섹션을 참조하십시오.
연결된 매개변수를 사용하여 URL을 열면 이미 애플리케이션에서 인증된 경우 어댑터에서 Red Hat Single Sign-On으로 리디렉션하지 않습니다. 예를 들어 이미 애플리케이션 mysecuredapp
에 인증된 경우 http://myappserver/mysecuredapp?prompt=login를 열면 Red Hat Single Sign-On 로그인 페이지로 자동으로 리디렉션되지 않습니다. 이 동작은 향후 변경될 수 있습니다.
2.1.14. 클라이언트 인증
기밀 OIDC 클라이언트가 백채널 요청을 보내야 하는 경우(예: 토큰의 코드를 교환하거나 토큰을 새로 고침) Red Hat Single Sign-On 서버에 대해 인증해야 합니다. 기본적으로 클라이언트를 인증하는 방법에는 클라이언트 ID와 클라이언트 시크릿, 서명된 JWT의 클라이언트 인증 또는 클라이언트 시크릿을 사용하여 서명된 JWT의 클라이언트 인증 세 가지가 있습니다.
2.1.14.1. 클라이언트 ID 및 클라이언트 보안
OAuth2 사양에 설명된 기존 방법입니다. 클라이언트에는 시크릿이 있으며 어댑터(애플리케이션)와 Red Hat Single Sign-On 서버 둘 다에 알려야 합니다. Red Hat Single Sign-On Admin Console에서 특정 클라이언트에 대한 시크릿을 생성한 다음 애플리케이션 측의 keycloak.json
파일에 이 시크릿을 붙여넣을 수 있습니다.
"credentials": { "secret": "19666a4f-32dd-4049-b082-684c74115f28" }
"credentials": {
"secret": "19666a4f-32dd-4049-b082-684c74115f28"
}
2.1.14.2. 서명 JWT를 사용한 클라이언트 인증
이는 RFC7523 사양을 기반으로 합니다. 이 방법은 다음과 같습니다.
-
클라이언트에는 개인 키와 인증서가 있어야 합니다. Red Hat Single Sign-On의 경우 클라이언트 애플리케이션의 클래스 경로 또는 파일 시스템 위치에서 사용할 수 있는 기존
키 저장소
파일을 통해 사용할 수 있습니다. - 클라이언트 애플리케이션이 시작되면 http://myhost.com/myapp가 클라이언트 애플리케이션의 기본 URL이라고 가정하면 http://myhost.com/myapp/k_jwks과 같은 URL을 사용하여 JWKS 형식으로 공개 키를 다운로드할 수 있습니다. 이 URL은 Red Hat Single Sign-On에서 사용할 수 있습니다(아래 참조).
-
인증 중에 클라이언트는 JWT 토큰을 생성하여 개인 키를 사용하여 서명하고
client_assertion
매개변수의 특정 백채널 요청(예: code-to-token 요청)에서 Red Hat Single Sign-On으로 보냅니다. Red Hat Single Sign-On에는 JWT의 서명을 확인할 수 있도록 클라이언트의 공개 키 또는 인증서가 있어야 합니다. Red Hat Single Sign-On에서 클라이언트의 클라이언트 자격 증명을 구성해야 합니다. 먼저 Admin Console의
Credentials
(자격 증명) 탭에서 클라이언트를 인증하는 방법으로Signed JWT
를 선택해야 합니다. 그런 다음 다음키
탭에서 선택할 수 있습니다.-
Red Hat Single Sign-On이 클라이언트의 공개 키를 다운로드할 수 있는 JWKS URL을 구성합니다. http://myhost.com/myapp/k_jwks과 같은 URL일 수 있습니다(위의 세부 정보 참조). 클라이언트가 언제든지 키를 회전시키고 Red Hat Single Sign-On은 구성을 변경하지 않고도 항상 새 키를 다운로드할 수 있기 때문에 이 옵션이 가장 유연합니다. 보다 정확하게 말해 Red Hat Single Sign-On은 알 수 없는 키(Key ID)가 서명한 토큰이 표시될 때 새 키를 다운로드합니다.
- 클라이언트의 공개 키 또는 인증서를 JWK 형식 또는 키 저장소에서 PEM 형식으로 업로드합니다. 이 옵션을 사용하면 공개 키가 하드 코딩되므로 클라이언트가 새 키 쌍을 생성할 때 변경해야 합니다. Red Hat Single Sign-On 관리 콘솔에서 자체 키 저장소를 생성할 수도 있습니다. Red Hat Single Sign-On 관리 콘솔을 설정하는 방법에 대한 자세한 내용은 서버 관리 가이드를 참조하십시오.
-
Red Hat Single Sign-On이 클라이언트의 공개 키를 다운로드할 수 있는 JWKS URL을 구성합니다. http://myhost.com/myapp/k_jwks과 같은 URL일 수 있습니다(위의 세부 정보 참조). 클라이언트가 언제든지 키를 회전시키고 Red Hat Single Sign-On은 구성을 변경하지 않고도 항상 새 키를 다운로드할 수 있기 때문에 이 옵션이 가장 유연합니다. 보다 정확하게 말해 Red Hat Single Sign-On은 알 수 없는 키(Key ID)가 서명한 토큰이 표시될 때 새 키를 다운로드합니다.
어댑터 측에 설정하려면 keycloak.json
파일에 다음과 같은 내용이 있어야 합니다.
"credentials": { "jwt": { "client-keystore-file": "classpath:keystore-client.jks", "client-keystore-type": "JKS", "client-keystore-password": "storepass", "client-key-password": "keypass", "client-key-alias": "clientkey", "algorithm": "RS256", "token-expiration": 10 } }
"credentials": {
"jwt": {
"client-keystore-file": "classpath:keystore-client.jks",
"client-keystore-type": "JKS",
"client-keystore-password": "storepass",
"client-key-password": "keypass",
"client-key-alias": "clientkey",
"algorithm": "RS256",
"token-expiration": 10
}
}
이 구성을 사용하면 WAR의 classpath에서 키 저장소 파일 keystore-client.jks
를 사용할 수 있어야 합니다. 접두사 classpath
를 사용하지 않는 경우 클라이언트 애플리케이션이 실행 중인 파일 시스템에서 파일을 가리킬 수 있습니다.
algorithm
필드는 Signed JWT에 사용되는 알고리즘을 지정하고 기본값은 RS256
입니다. 이 필드는 키 쌍과 동기화되어야 합니다. 예를 들어, RS256
알고리즘에는 ES256
알고리즘에 EC 키 쌍이 필요한 반면 RSA 키 쌍이 필요합니다. 자세한 내용은 디지털 서명 및 MAC에 대한 IRQ 그래픽 알고리즘 을 참조하십시오.
2.1.15. 멀티 테넌시
Red Hat의 컨텍스트에서 Multi Tenancy는 여러 Red Hat Single Sign-On 영역으로 단일 대상 애플리케이션(WAR)을 보호할 수 있음을 의미합니다. 이 영역은 동일한 Red Hat Single Sign-On 인스턴스 또는 다른 인스턴스에 있을 수 있습니다.
실제로 애플리케이션에는 여러 keycloak.json
어댑터 구성 파일이 있어야 합니다.
다른 컨텍스트 경로에 배포된 다양한 어댑터 구성 파일이 있는 WAR 인스턴스가 여러 개 있을 수 있습니다. 그러나 이 방법은 불편할 수 있으며 context-path 이외의 다른 항목을 기반으로 영역을 선택할 수도 있습니다.
Red Hat Single Sign-On을 사용하면 사용자 정의 구성 해결 프로그램을 사용할 수 있으므로 각 요청에 사용되는 어댑터 구성을 선택할 수 있습니다.
이를 위해 먼저 org.keycloak.adapters.KeycloakConfigResolver
구현을 생성해야 합니다. 예를 들면 다음과 같습니다.
package example; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeploymentBuilder; public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver { @Override public KeycloakDeployment resolve(OIDCHttpFacade.Request request) { if (path.startsWith("alternative")) { KeycloakDeployment deployment = cache.get(realm); if (null == deployment) { InputStream is = getClass().getResourceAsStream("/tenant1-keycloak.json"); return KeycloakDeploymentBuilder.build(is); } } else { InputStream is = getClass().getResourceAsStream("/default-keycloak.json"); return KeycloakDeploymentBuilder.build(is); } } }
package example;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
if (path.startsWith("alternative")) {
KeycloakDeployment deployment = cache.get(realm);
if (null == deployment) {
InputStream is = getClass().getResourceAsStream("/tenant1-keycloak.json");
return KeycloakDeploymentBuilder.build(is);
}
} else {
InputStream is = getClass().getResourceAsStream("/default-keycloak.json");
return KeycloakDeploymentBuilder.build(is);
}
}
}
web.xml
의 keycloak.config.resolver
context-param과 함께 사용할 KeycloakConfigResolver
구현을 구성해야 합니다.
<web-app> ... <context-param> <param-name>keycloak.config.resolver</param-name> <param-value>example.PathBasedKeycloakConfigResolver</param-value> </context-param> </web-app>
<web-app>
...
<context-param>
<param-name>keycloak.config.resolver</param-name>
<param-value>example.PathBasedKeycloakConfigResolver</param-value>
</context-param>
</web-app>
2.1.16. 애플리케이션 클러스터링
이 장에서는 JBoss EAP에 배포된 클러스터된 애플리케이션 지원과 관련이 있습니다.
애플리케이션이 다음과 같은지 여부에 따라 몇 가지 옵션을 사용할 수 있습니다.
- 상태 비저장 또는 상태 저장
- 배포 가능(복제 가능 http 세션) 또는 배포되지 않음
- 로드 밸런서에서 제공하는 고정 세션에 사용
- Red Hat Single Sign-On과 동일한 도메인에서 호스팅
클러스터링을 처리하는 것은 일반 애플리케이션에서처럼 간단하지 않습니다. 주로 브라우저와 서버 측 애플리케이션이 Red Hat Single Sign-On에 요청을 전송하므로 로드 밸런서에서 고정 세션을 활성화하는 것처럼 간단하지 않습니다.
2.1.16.1. 상태 비저장 토큰 저장소
기본적으로 Red Hat Single Sign-On에서 보호하는 웹 애플리케이션은 HTTP 세션을 사용하여 보안 컨텍스트를 저장합니다. 즉, 고정 세션을 활성화하거나 HTTP 세션을 복제해야 합니다.
HTTP 세션에 보안 컨텍스트를 저장하는 대안으로 어댑터를 구성할 수 있습니다. 대신 이를 쿠키 내에 저장하도록 어댑터를 구성할 수 있습니다. 이 기능은 애플리케이션을 상태 비저장으로 설정하거나 HTTP 세션에 보안 컨텍스트를 저장하지 않으려면 유용합니다.
보안 컨텍스트를 저장하기 위해 쿠키 저장소를 사용하려면, 애플리케이션 ^ -INF/keycloak.json
을 편집하고 다음을 추가합니다.
"token-store": "cookie"
"token-store": "cookie"
token-store
의 기본값은 HTTP 세션에
보안 컨텍스트를 저장하는 세션입니다.
쿠키 저장소 사용의 한 가지 제한은 전체 보안 컨텍스트가 모든 HTTP 요청에 대해 쿠키로 전달된다는 것입니다. 이는 성능에 영향을 미칠 수 있습니다.
또 다른 작은 제한은 Single-Sign Out에 대한 지원이 제한됩니다. 어댑터가 KEYCLOAK_ADAPTER_STATE 쿠키를 삭제하므로 애플리케이션 자체에서 서블릿 logout(HttpServletRequest.logout)을 초기화하면 문제 없이 작동합니다. 그러나 다른 애플리케이션에서 초기화된 백 채널 로그는 Red Hat Single Sign-On에서 쿠키 저장소를 사용하는 애플리케이션에 전파되지 않습니다. 따라서 액세스 토큰 시간 초과에 짧은 값을 사용하는 것이 좋습니다(예: 1분).
일부 로드 밸런서에서는 Amazon ALB와 같은 고정 세션 쿠키 이름 또는 콘텐츠의 구성을 허용하지 않습니다. 이러한 경우 shouldAttachRoute
옵션을 false
로 설정하는 것이 좋습니다.
2.1.16.2. 상대 URI 최적화
Red Hat Single Sign-On과 애플리케이션이 동일한 도메인에서 호스팅되는 배포 시나리오에서는 클라이언트 구성에서 상대 URI 옵션을 사용하는 것이 편리합니다.
상대 URI를 사용하면 Red Hat Single Sign-On에 액세스하는 데 사용되는 URL에 상대적으로 URI가 확인됩니다.
예를 들어 애플리케이션의 URL이 https://acme.org/myapp
이고 Red Hat Single Sign-On의 URL이 https://acme.org/auth
인 경우 https://acme.org/myapp
대신 redirect-uri /myapp
을 사용할 수 있습니다.
2.1.16.3. 관리자 URL 구성
특정 클라이언트의 관리자 URL은 Red Hat Single Sign-On 관리 콘솔에서 구성할 수 있습니다. Red Hat Single Sign-On 서버에서는 로그아웃 사용자 또는 해지 정책과 같은 다양한 작업의 백엔드 요청을 애플리케이션에 보내는 데 사용됩니다.
예를 들어 backchannel logout 작동 방식은 다음과 같습니다.
- 사용자가 하나의 애플리케이션에서 로그 아웃 요청을 보냅니다.
- 애플리케이션이 Red Hat Single Sign-On에 로그 아웃 요청을 보냅니다.
- Red Hat Single Sign-On 서버에서 사용자 세션 무효화
- Red Hat Single Sign-On 서버는 세션과 연결된 관리자 URL이 있는 애플리케이션에 백채널 요청을 보냅니다.
- 애플리케이션에서 로그아웃 요청을 수신하면 해당 HTTP 세션이 무효화됩니다.
관리자 URL에 ${application.session.host}
가 포함된 경우 HTTP 세션과 연결된 노드의 URL로 교체됩니다.
2.1.16.4. 애플리케이션 노드 등록
이전 섹션에서는 Red Hat Single Sign-On이 특정 HTTP 세션과 연결된 노드에 로그 아웃 요청을 보내는 방법을 설명합니다. 그러나 경우에 따라 admin은 둘 중 하나만이 아닌 등록된 모든 클러스터 노드에 관리 작업을 전파할 수 있습니다. 예를 들어 정책 이전의 새 정책을 애플리케이션에 내보내거나 애플리케이션에서 모든 사용자를 로그아웃하는 경우입니다.
이 경우 Red Hat Single Sign-On은 모든 애플리케이션 클러스터 노드를 알고 있어야 하므로 이벤트를 모든 사용자에게 보낼 수 있습니다. 이를 위해 자동 검색 메커니즘을 지원합니다.
- 새 애플리케이션 노드가 클러스터에 참여하면 Red Hat Single Sign-On 서버에 등록 요청을 보냅니다.
- 구성된 주기적인 간격으로 Red Hat Single Sign-On에 다시 요청을 받을 수 있습니다.
- Red Hat Single Sign-On 서버에서 지정된 시간 초과 내에 재등록 요청을 수신하지 못하면 특정 노드를 자동으로 등록 취소합니다.
- Red Hat Single Sign-On에서 노드는 노드 종료 또는 애플리케이션 배포 취소 중인 등록 취소 요청을 보낼 때 Red Hat Single Sign-On에서 등록되지 않습니다. 이 작업은 undeployment 리스너가 호출되지 않은 경우 강제 종료 시 제대로 작동하지 않을 수 있으므로 자동 등록 해제가 필요합니다.
시작 등록 및 정기적인 재등록 전송은 일부 클러스터된 애플리케이션에만 필요하므로 기본적으로 비활성화됩니다.
기능 편집을 활성화하려면 애플리케이션에 대해 WEB-INF/keycloak.json
파일을 추가하고 다음을 추가합니다.
"register-node-at-startup": true, "register-node-period": 600,
"register-node-at-startup": true,
"register-node-period": 600,
즉 어댑터는 시작시 등록 요청을 보내고 10분마다 다시 등록합니다.
Red Hat Single Sign-On 관리 콘솔에서 최대 노드 재등록 시간 초과를 지정할 수 있습니다( 어댑터 구성에서 register-node-period 보다 커야 함). 자동 등록 기능을 사용하지 않거나 자동 등록 기능을 사용하지 않는 경우 유용한 관리 콘솔을 통해 클러스터 노드를 수동으로 추가하고 삭제할 수도 있습니다.
2.1.16.5. 각 요청에서 토큰 새로 고침
기본적으로 애플리케이션 어댑터는 만료된 경우에만 액세스 토큰을 새로 고칩니다. 그러나 모든 요청에서 토큰을 새로 고치도록 어댑터를 구성할 수도 있습니다. 애플리케이션이 Red Hat Single Sign-On 서버에 더 많은 요청을 전송하므로 성능에 영향을 미칠 수 있습니다.
기능 편집을 활성화하려면 애플리케이션에 대해 WEB-INF/keycloak.json
파일을 추가하고 다음을 추가합니다.
"always-refresh-token": true
"always-refresh-token": true
이는 성능에 큰 영향을 미칠 수 있습니다. 정책 전에 로그아웃을 전파하기 위해 백채널 메시지를 사용할 수 없는 경우에만 이 기능을 활성화합니다. 고려해야 할 또 다른 사항은 기본적으로 액세스 토큰에 단기 만료가 있으므로 로그아웃 후 토큰이 전파되지 않더라도 로그아웃 후 몇 분 내에 토큰이 만료된다는 것입니다.
2.2. JavaScript adapter
Red Hat Single Sign-On에는 HTML5/JavaScript 애플리케이션을 보호하는 데 사용할 수 있는 클라이언트 측 JavaScript 라이브러리가 포함되어 있습니다. JavaScript 어댑터에는 Cordova 애플리케이션에 대한 지원이 내장되어 있습니다.
이러한 문제를 해결하기 위해서는 JavaScript 어댑터를 application에 포함시키는 것이 좋습니다. 이 어댑터는 10.0.0.1 또는 Yarn과 같은 패키지 관리자를 사용하여 애플리케이션에 추가하는 것입니다. keycloak-js
패키지는 다음 위치에서 사용할 수 있습니다.
또는 /auth/js/keycloak.js
의 Red Hat Single Sign-On 서버에서 직접 라이브러리를 검색할 수 있으며 ZIP 아카이브로 배포됩니다.
클라이언트 측 애플리케이션 사용에 대해 유의해야 할 한 가지 중요한 사항은 클라이언트 측 애플리케이션에 클라이언트 자격 증명을 저장하는 안전한 방법이 없기 때문에 클라이언트가 공용 클라이언트여야 한다는 것입니다. 이렇게 하면 클라이언트에 대해 구성한 리디렉션 URI가 정확하고 가능한 한 구체적으로 확인하는 것이 매우 중요합니다.
JavaScript 어댑터를 사용하려면 먼저 Red Hat Single Sign-On 관리 콘솔에서 애플리케이션에 사용할 클라이언트를 생성해야 합니다. 액세스
유형에 대해 공용
이 선택되어 있는지 확인합니다. 이 작업은 OFF 클라이언트 인증 토글을 전환하여 Capability config에서 수행할 수 있습니다.
또한 유효한 리디렉션 URI
및 Web Origins
를 구성해야 합니다. 가능한 한 구체적으로 하지 않으면 보안 취약점이 발생할 수 있습니다.
클라이언트가 생성되면 오른쪽 상단에 있는 Action
탭을 클릭하고 Download adapter config
를 선택합니다. 형식 옵션에 대해
다음 Keycloak OIDC JSON
을 선택한다운로드를
클릭합니다. 다운로드한 keycloak.json
파일은 웹 서버에서 HTML 페이지와 동일한 위치에 호스팅되어야 합니다.
또는 구성 파일을 건너뛰고 어댑터를 수동으로 구성할 수 있습니다.
다음 예제에서는 JavaScript 어댑터를 초기화하는 방법을 보여줍니다.
<html> <head> <script src="keycloak.js"></script> <script> function initKeycloak() { const options = {}; const keycloak = new Keycloak(); keycloak.init(options) .then(function(authenticated) { console.log('keycloak:' + (authenticated ? 'authenticated' : 'not authenticated')); }).catch(function(error) { for (const property in error) { console.error(`${property}: ${error[property]}`); } }); } </script> </head> <body onload="initKeycloak()"> <!-- your page content goes here --> </body> </html>
<html>
<head>
<script src="keycloak.js"></script>
<script>
function initKeycloak() {
const options = {};
const keycloak = new Keycloak();
keycloak.init(options)
.then(function(authenticated) {
console.log('keycloak:' + (authenticated ? 'authenticated' : 'not authenticated'));
}).catch(function(error) {
for (const property in error) {
console.error(`${property}: ${error[property]}`);
}
});
}
</script>
</head>
<body onload="initKeycloak()">
<!-- your page content goes here -->
</body>
</html>
keycloak.json
파일이 다른 위치에 있는 경우 다음을 지정할 수 있습니다.
const keycloak = new Keycloak('http://localhost:8080/myapp/keycloak.json');
const keycloak = new Keycloak('http://localhost:8080/myapp/keycloak.json');
또는 다음과 같이 필요한 구성을 사용하여 JavaScript 개체를 전달할 수 있습니다.
const keycloak = new Keycloak({ url: 'http://keycloak-server$/auth', realm: 'myrealm', clientId: 'myapp' });
const keycloak = new Keycloak({
url: 'http://keycloak-server$/auth',
realm: 'myrealm',
clientId: 'myapp'
});
기본적으로 인증하려면 로그인
함수를 호출해야 합니다. 그러나 어댑터를 자동으로 인증할 수 있는 두 가지 옵션이 있습니다. login-required
또는 check-sso
를 init 함수에 전달할 수 있습니다. 사용자가 Red Hat Single Sign-On에 로그인한 경우 로그인이 필요한
경우 클라이언트를 인증하거나 그렇지 않은 경우 로그인 페이지를 표시합니다. check-sso
는 사용자가 이미 로그인한 경우에만 클라이언트를 인증합니다. 브라우저가 로그인되지 않은 경우 다시 애플리케이션으로 리디렉션되고 인증되지 않은 상태로 유지됩니다.
자동 check-sso
옵션을 구성할 수 있습니다. 이 기능을 사용하면 브라우저가 Red Hat Single Sign-On 서버로 전체 리디렉션을 수행하지 않고 애플리케이션에 다시 리디렉션되지 않지만 숨겨진 iframe에서 이 작업을 수행할 수 있으므로, 애플리케이션이 초기화될 때 브라우저에서 한 번만 로드하고 구문 분석하면 Red Hat Single Sign-On에서 다시 리디렉션되지 않습니다. 이는 SPA(Single Page Applications)의 경우 특히 유용합니다.
자동 check-sso
를 활성화하려면 init 메서드에서 silentCheckSsoRedirectUri
속성을 제공해야 합니다. 이 URI는 애플리케이션에서 유효한 엔드포인트여야 하며, Red Hat Single Sign-On 관리 콘솔에서 클라이언트에 대한 유효한 리디렉션으로 구성해야 합니다.
keycloak.init({ onLoad: 'check-sso', silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html' })
keycloak.init({
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'
})
인증 상태를 성공적으로 확인하고 Red Hat Single Sign-On 서버에서 토큰을 검색한 후 자동 check-sso 리디렉션 uri의 페이지가 iframe에 로드됩니다. 수신한 토큰을 기본 애플리케이션에 보내는 것 외에는 다른 작업이 없으며 다음과 같이 표시되어야 합니다.
<html> <body> <script> parent.postMessage(location.href, location.origin) </script> </body> </html>
<html>
<body>
<script>
parent.postMessage(location.href, location.origin)
</script>
</body>
</html>
지정된 위치에 있는 이 페이지는 애플리케이션 자체에서 제공해야 하며 JavaScript 어댑터의 일부가 아닙니다!
자동 검사 기능은
일부 최신 브라우저에서 제한됩니다. 추적 보호 기능이 있는 최신 website를 참조하십시오.
Load에서
login-required
를 login-required
로 설정하고 init 메서드로 전달하려면 다음을 수행합니다.
keycloak.init({ onLoad: 'login-required' })
keycloak.init({
onLoad: 'login-required'
})
사용자가 인증되면 애플리케이션은 권한 부여
헤더에 전달자 토큰을 포함하여 Red Hat Single Sign-On에서 보호한 RESTful 서비스에 요청할 수 있습니다. 예를 들면 다음과 같습니다.
const loadData = function () { document.getElementById('username').innerText = keycloak.subject; const url = 'http://localhost:8080/restful-service'; const req = new XMLHttpRequest(); req.open('GET', url, true); req.setRequestHeader('Accept', 'application/json'); req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token); req.onreadystatechange = function () { if (req.readyState == 4) { if (req.status == 200) { alert('Success'); } else if (req.status == 403) { alert('Forbidden'); } } } req.send(); };
const loadData = function () {
document.getElementById('username').innerText = keycloak.subject;
const url = 'http://localhost:8080/restful-service';
const req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
alert('Success');
} else if (req.status == 403) {
alert('Forbidden');
}
}
}
req.send();
};
한 가지 유의할 점은 액세스 토큰에 기본적으로 짧은 수명이 만료되므로 요청을 보내기 전에 액세스 토큰을 새로 고쳐야 할 수 있다는 것입니다. updateToken
메서드로 이 작업을 수행할 수 있습니다. updateToken
메서드는 토큰이 성공적으로 새로 고쳐진 경우에만 서비스를 쉽게 호출할 수 있도록 하고 그렇지 않은 경우 사용자에게 오류를 표시할 수 있도록 합니다. 예를 들면 다음과 같습니다.
keycloak.updateToken(30).then(function() { loadData(); }).catch(function() { alert('Failed to refresh token'); });
keycloak.updateToken(30).then(function() {
loadData();
}).catch(function() {
alert('Failed to refresh token');
});
2.2.1. 세션 상태 iframe
기본적으로 JavaScript 어댑터는 Single-Sign Out이 발생했는지를 감지하는 데 사용되는 숨겨진 iframe을 만듭니다. 이 명령은 네트워크 트래픽이 필요하지 않으며, 대신 특수 상태 쿠키를 확인하여 상태를 검색합니다. 이 기능은 init
메서드로 전달되는 옵션에서 checkLoginIframe: false
를 설정하여 비활성화할 수 있습니다.
이 쿠키를 직접 확인하는 데 의존해서는 안 됩니다. 해당 형식은 변경될 수 있으며 애플리케이션이 아닌 Red Hat Single Sign-On 서버의 URL과도 연결됩니다.
세션 상태 iframe 기능은 일부 최신 브라우저에서 제한됩니다. 추적 방지 섹션이 있는 Modernloadbalancings를 참조하십시오.
2.2.2. 암시적 및 하이브리드 흐름
기본적으로 JavaScript 어댑터는 인증 코드 흐름을 사용합니다.
이 흐름을 통해 Red Hat Single Sign-On 서버는 인증 토큰이 아닌 권한 부여 코드를 애플리케이션에 반환합니다. JavaScript 어댑터는 브라우저가
애플리케이션으로 리디렉션된 후 액세스 토큰과 새로 고침 토큰을 교체합니다.
Red Hat Single Sign-On은 Red Hat Single Sign-On을 사용한 성공적인 인증 직후 액세스 토큰이 전송되는 Implicit flow를 지원합니다. 토큰 코드를 교환하라는 추가 요청이 없기 때문에 표준 흐름보다 성능이 향상될 수 있지만 액세스 토큰이 만료되면 영향을 미칩니다.
그러나 URL 조각에 액세스 토큰을 전송하는 것은 보안 취약점이 될 수 있습니다. 예를 들어 웹 서버 로그 및 브라우저 기록을 통해 토큰이 유출될 수 있습니다.
암시적 흐름을 활성화하려면 Red Hat Single Sign-On 관리 콘솔에서 클라이언트에 대해 Implicit Flow Enabled
플래그를 활성화해야 합니다. 또한 값이 암시적인
init
메서드로 매개변수 흐름을
전달해야 합니다.
keycloak.init({ flow: 'implicit' })
keycloak.init({
flow: 'implicit'
})
한 가지 주목할 점은 액세스 토큰만 제공되며 새로 고침 토큰이 없다는 것입니다. 즉, 액세스 토큰이 만료되면 애플리케이션이 Red Hat Single Sign-On으로 리디렉션하여 새 액세스 토큰을 다시 가져와야 합니다.
Red Hat Single Sign-On은 하이브리드 흐름도 지원합니다.
이를 위해 클라이언트는 관리 콘솔에서 표준 흐름 사용
및 Implicit Flow Enabled
플래그를 모두 사용하도록 설정해야 합니다. 그러면 Red Hat Single Sign-On 서버가 애플리케이션에 코드와 토큰을 모두 보냅니다. 액세스 및 새로 고침 토큰을 위해 코드를 교환하는 동안 즉시 액세스 토큰을 사용할 수 있습니다. 암시적 흐름과 유사하게, 액세스 토큰을 즉시 사용할 수 있기 때문에 하이브리드 흐름이 성능에 적합합니다. 그러나 토큰은 URL로 계속 전송되며 이전에 언급한 보안 취약점이 계속 적용될 수 있습니다.
하이브리드 흐름의 한 가지 장점은 새로 고침 토큰을 애플리케이션에 사용할 수 있다는 것입니다.
하이브리드 흐름의 경우 값 하이브리드
를 사용하여 매개 변수 흐름을
init
메서드에 전달해야 합니다.
keycloak.init({ flow: 'hybrid' })
keycloak.init({
flow: 'hybrid'
})
2.2.3. Cordova를 사용한 하이브리드 앱
Keycloak은 Apache Cordova 로 개발된 하이브리드 모바일 애플리케이션을 지원합니다. JavaScript 어댑터에는 cordova
및 cordova-native
의 두 가지 모드가 있습니다.
기본값은 cordova이며 어댑터 유형이 구성되지 않은 경우 어댑터가 자동으로 선택되고 window.cordova가 있습니다. 로그인할 때 사용자가 Red Hat Single Sign-On과 상호 작용하고 나중에 http://localhost
로 리디렉션하여 애플리케이션으로 돌아갈 수 있는 InApp browser가 열립니다. 이로 인해 Admin Console의 클라이언트 구성 섹션에 이 URL을 유효한 redirect-uri로 허용 목록에 추가해야 합니다.
이 모드는 설정하기 쉽지만 몇 가지 단점도 있습니다.
- InApp-Forwardedr는 앱에 포함된 브라우저이며 휴대폰의 기본 브라우저가 아닙니다. 따라서 설정이 다르며 저장된 자격 증명을 사용할 수 없습니다.
- 특히 더 복잡한 요소를 렌더링할 때 InApp->-<r도 느려질 수 있습니다.
- 이 모드를 사용하기 전에 앱이 로그인 페이지를 렌더링하는 브라우저를 완전히 제어할 수 있으므로 신뢰할 수 없는 앱에서의 사용을 허용하지 않도록 이 모드를 사용하기 전에 고려해야 할 사항이 있습니다.
이 예제 앱을 사용하여 시작하는 데 도움이 됩니다. https://github.com/keycloak/keycloak/tree/master/examples/cordova
대체 모드 cordova-native
는 다른 접근 방식을 취합니다. 시스템 브라우저를 사용하여 로그인 페이지를 엽니다. 사용자가 인증되면 브라우저가 특수 URL을 사용하여 앱에 다시 리디렉션됩니다. 여기에서 Red Hat Single Sign-On 어댑터는 URL에서 코드 또는 토큰을 읽고 로그인을 완료할 수 있습니다.
어댑터 유형 cordova-native
를 init
메서드에 전달하여 기본 모드를 활성화할 수 있습니다.
keycloak.init({ adapter: 'cordova-native' })
keycloak.init({
adapter: 'cordova-native'
})
이 어댑터에는 두 개의 추가 플러그인이 필요합니다.
- Cordova-plugin-browsertab: 앱이 시스템 브라우저에서 웹 페이지를 열 수 있습니다.
- Cordova-plugin-deeplinks: 브라우저가 특수 URL로 다시 리디렉션되도록 허용
앱에 연결하는 데 필요한 기술적 세부 사항은 플랫폼마다 다르며 특수 설정이 필요합니다. 자세한 내용은 딥링크 플러그인 문서 의 안 드 로이드 및 iOS 섹션을 참조하십시오.
앱 열기 방법에는 사용자 지정 체계(예: myapp://login
또는 iPXE -app://com.example.myapp/https/example.com/login
) 및 Universal Links (iOS)) / Deep Links( octavia)의 다양한 종류가 있습니다. 전자는 설정하기가 쉽고 더 안정적으로 작동하는 경향이 있지만 나중에 고유하므로 도메인 소유자 만 추가 보안을 제공합니다. Custom-URLs는 iOS에서 더 이상 사용되지 않습니다. 최상의 안정성을 위해 사용자 정의 URL 링크가 포함된 대체 사이트와 결합된 범용 링크를 사용하는 것이 좋습니다.
또한 Keycloak 어댑터와의 호환성을 개선하기 위해 다음 단계를 권장합니다.
-
iOS의 Universal Links가
쿼리
로 설정된응답 모드를
사용하여 보다 안정적으로 작동하는 것처럼 보입니다. -
incorrect가 리디렉션에서 앱의 새 인스턴스를 열지 못하도록 하려면
config.xml
에 다음 스니펫을 추가합니다.
<preference name="AndroidLaunchMode" value="singleTask" />
<preference name="AndroidLaunchMode" value="singleTask" />
네이티브 모드 사용 방법을 보여주는 앱 예제: https://github.com/keycloak/keycloak/tree/master/examples/cordova-native
2.2.4. 사용자 정의 어댑터
경우에 따라 기본적으로 지원되지 않는 환경에서 JavaScript 클라이언트를 실행해야 합니다(예: Capacitor). 이러한 종류의 알 수 없는 환경에서 JavasScript 클라이언트를 사용할 수 있도록 사용자 지정 어댑터를 전달할 수 있습니다. 예를 들어, 타사 라이브러리에서는 이러한 어댑터를 제공하여 문제 없이 JavaScript 클라이언트를 실행할 수 있습니다.
import Keycloak from 'keycloak-js'; import KeycloakCapacitorAdapter from 'keycloak-capacitor-adapter'; const keycloak = new Keycloak(); keycloak.init({ adapter: KeycloakCapacitorAdapter, });
import Keycloak from 'keycloak-js';
import KeycloakCapacitorAdapter from 'keycloak-capacitor-adapter';
const keycloak = new Keycloak();
keycloak.init({
adapter: KeycloakCapacitorAdapter,
});
이 특정 패키지는 존재하지 않지만 이러한 어댑터를 클라이언트에 전달하는 방법에 대한 좋은 예를 제공합니다.
또한 고유한 어댑터를 만들 수 있으므로 KeycloakAdapter
인터페이스에 설명된 메서드를 구현해야 합니다. 예를 들어 다음 TypeScript 코드는 모든 메서드가 올바르게 구현되도록 합니다.
import Keycloak, { KeycloakAdapter } from 'keycloak-js'; // Implement the 'KeycloakAdapter' interface so that all required methods are guaranteed to be present. const MyCustomAdapter: KeycloakAdapter = { login(options) { // Write your own implementation here. } // The other methods go here... }; const keycloak = new Keycloak(); keycloak.init({ adapter: MyCustomAdapter, });
import Keycloak, { KeycloakAdapter } from 'keycloak-js';
// Implement the 'KeycloakAdapter' interface so that all required methods are guaranteed to be present.
const MyCustomAdapter: KeycloakAdapter = {
login(options) {
// Write your own implementation here.
}
// The other methods go here...
};
const keycloak = new Keycloak();
keycloak.init({
adapter: MyCustomAdapter,
});
당연히 유형 정보를 생략하여 TypeScript 없이 이 작업을 수행할 수도 있지만, 인터페이스를 올바르게 구현하는 것은 전적으로 사용자에게 맡겨집니다.
2.2.5. 이전 browsers
JavaScript 어댑터는 Base64(window.btoa 및 window.atob), HTML5 기록 API 및 선택적으로 Promise API에 따라 다릅니다. 사용할 수 없는 브라우저 (예: IE9)를 지원해야 하는 경우 polyfiller를 추가해야 합니다.
예제 polyfill 라이브러리:
2.2.6. 추적 보호 기능이 있는 최신 website
일부 브라우저의 최신 버전에서 다양한 쿠키 정책이 적용되어 Chrome의 SameSite와 같은 타사 쿠키를 추적하거나 타사 쿠키를 완전히 차단할 수 있습니다. 이러한 정책이 더욱 제한되고 시간이 지남에 따라 다른 브라우저에서 채택되어 결국 타사 컨텍스트에서 쿠키가 완전히 지원되고 차단될 것으로 예상됩니다. 이 문제의 영향을 받는 어댑터 기능은 나중에 더 이상 사용되지 않을 수 있습니다.
JavaScript 어댑터는 세션 상태 iframe, 자동 검사에
대한 타사 쿠키를 사용하고 일부는 일반 (비일명) 검사를 위해 부분적으로 사용됩니다
. 이러한 기능은 기능이 제한되거나 브라우저가 쿠키와 관련하여 제한적인 방법에 따라 완전히 비활성화되어 있습니다. 어댑터는 이 설정을 탐지하여 적절하게 대응합니다.
2.2.6.1. "SameSite=L Galaxy by Default" 정책이 있는 브라우저
애플리케이션 측뿐만 아니라 Red Hat Single Sign-On 측에 SSL/TLS 연결이 구성된 경우 모든 기능이 지원됩니다. 이는 버전 84부터 Chrome의 영향을 받습니다.
2.2.6.2. 차단된 타사 쿠키 사용 브라우저
세션 상태 iframe은 지원되지 않으며 JS 어댑터에서 이러한 브라우저 동작이 감지되면 자동으로 비활성화됩니다. 즉 어댑터는 Single Sign-Out 감지에 세션 쿠키를 사용할 수 없으며 토큰에 전적으로 의존해야 합니다. 즉, 사용자가 다른 창에서 로그아웃하면 JavaScript 어댑터를 사용하는 애플리케이션은 액세스 토큰을 새로 고침하려고 할 때까지 로그아웃되지 않습니다. 따라서 액세스 토큰 라이프스패스를 상대적으로 짧은 시간으로 설정하여 로그 아웃이 나중에 아닌 더 빨리 감지되도록 하는 것이 좋습니다. 세션 및 토큰 시간 초과를 참조하십시오.
자동
는 지원되지 않으며 기본적으로 일반(일실) 검사로 대체됩니다. 이 동작은 check-sso
init
메서드로 전달된 옵션에 silentCheckSsoFallback: false
를 설정하여 변경할 수 있습니다. 이 경우 제한적인 브라우저 동작이 감지되면 check-sso
는 완전히 비활성화됩니다.
정기 적인 검사
도 영향을 받습니다. 세션 상태 iframe은 지원되지 않으므로 어댑터가 초기화되어 사용자의 로그인 상태를 확인하도록 Red Hat Single Sign-On에 대한 추가 리디렉션을 수행해야 합니다. 이 동작은 사용자가 로그인했는지 여부를 확인하는 데 iframe을 사용하는 경우 표준 동작과 다르며 로그아웃된 경우에만 리디렉션이 수행됩니다.
영향을 받는 브라우저는 예를 들어 버전 13.1부터 시작하여 Safari입니다.
2.2.7. JavaScript Adapter 참조
2.2.7.1. 생성자
new Keycloak(); new Keycloak('http://localhost/keycloak.json'); new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' });
new Keycloak();
new Keycloak('http://localhost/keycloak.json');
new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' });
2.2.7.2. 속성
- authenticated
-
사용자가 인증되면
true
이고, 그렇지 않으면false
입니다. - 토큰
-
요청에
권한 부여
헤더로 보낼 수 있는 base64 인코딩 토큰입니다. - tokenParsed
- JavaScript 오브젝트로 구문 분석된 토큰입니다.
- subject
- 사용자 ID입니다.
- idToken
- base64로 인코딩된 ID 토큰입니다.
- idTokenParsed
- JavaScript 오브젝트로 구문 분석된 id 토큰입니다.
- realmAccess
- 토큰과 연결된 영역 역할입니다.
- resourceAccess
- 토큰과 연결된 리소스 역할입니다.
- refreshToken
- 새 토큰을 검색하는 데 사용할 수 있는 base64로 인코딩된 새로 고침 토큰입니다.
- refreshTokenParsed
- 구문 분석된 새로 고침 토큰을 JavaScript 오브젝트로 사용합니다.
- timeSkew
- 브라우저 시간과 Red Hat Single Sign-On 서버 간의 예상 시간 차이(초)입니다. 이 값은 추정치일 뿐이지만 토큰이 만료되었는지 여부를 확인할 때 충분히 정확합니다.
- responseMode
- init로 전달되는 응답 모드(기본값은 조각임).
- flow
- init에서 전달된 흐름입니다.
- Adapter
라이브러리에서 리디렉션 및 기타 브라우저 관련 기능을 처리하는 방법을 재정의할 수 있습니다. 사용 가능한 옵션:
- "default" - 라이브러리에서 리디렉션에 브라우저 api를 사용합니다(기본값: 기본값)
- "Cordova" - 라이브러리는 InApp>-<r cordova 플러그인을 사용하여 키cloak 로그인/등록 페이지를 로드하려고 합니다. 라이브러리가 cordova 에코시스템에서 작업할 때 자동으로 사용됩니다.
- "Cordova-native" - 라이브러리는 browserTabs cordova 플러그인을 사용하여 휴대폰의 시스템 브라우저를 사용하여 로그인 및 등록 페이지를 엽니다. 이렇게 하려면 앱에 다시 리디렉션하려면 추가 설정이 필요합니다( 2.2.3절. “Cordova를 사용한 하이브리드 앱”참조).
- "custom" - 사용자 정의 어댑터를 구현할 수 있습니다 (고급 사용 사례 전용)
- responseType
- 로그인 요청과 함께 Red Hat Single Sign-On으로 전송된 응답 유형입니다. 이는 초기화 중에 사용되는 흐름 값에 따라 결정되지만 이 값을 설정하여 재정의할 수 있습니다.
2.2.7.3. 방법
init(options)
어댑터를 초기화하기 위해 호출됩니다.
옵션은 다음과 같은 오브젝트입니다.
-
useNonce - 암호화 nonce를 추가하여 인증 응답이 요청과 일치하는지 확인합니다(기본값은
true
). -
Onload - 로드 시 수행할 작업을 지정합니다. 지원되는 값은
login-required
또는check-sso
입니다. - silentCheckSsoRedirectUri - onLoad가 'check-sso'로 설정된 경우 자동 인증 검사를 위해 리디렉션 배를 설정합니다.
-
silentCheckSsoFallback - 자동
검사-sso
가 브라우저에서 지원되지 않는경우
(기본값은true
임) 일반 검사로 대체됩니다. - token - 토큰의 초기 값을 설정합니다.
- refreshToken - 새로 고침 토큰의 초기 값을 설정합니다.
- idToken - ID 토큰의 초기 값을 설정합니다( token 또는 refreshToken과 함께만).
-
범위 - 기본 범위 매개 변수를 Red Hat Single Sign-On 로그인 엔드포인트로 설정합니다. 공백으로 구분된 범위 목록을 사용합니다. 일반적으로 특정 클라이언트에 정의된 클라이언트 범위를 참조합니다. 범위
openid
는 항상 어댑터의 범위 목록에 추가됩니다. 예를 들어 범위 옵션주소 전화
번호를 입력하면 Red Hat Single Sign-On에 범위 매개 변수scope=openid 주소 전화가
포함됩니다.login()
옵션이 범위를 명시적으로 지정하는 경우 여기에 지정된 기본 범위를 덮어씁니다. - timeSkew - 로컬 시간과 Red Hat Single Sign-On 서버 간 스케이크 초기 값을 초 단위로 설정합니다( token 또는 refreshToken과 함께만).
-
checkLoginIframe - 모니터링 로그인 상태를 활성화/비활성화하도록 설정합니다(기본값은
true
). - checkLoginIframeInterval - 로그인 상태를 확인하도록 간격을 설정합니다(기본값은 5초).
-
responseMode - 로그인 요청 시 OpenID Connect 응답 모드를 Red Hat Single Sign-On 서버로 전송합니다. 유효한 값은
query
또는fragment
입니다. 기본값은조각입니다
. 즉, 인증에 성공하면 Red Hat Single Sign-On이 URL 조각에 OpenID Connect 매개변수를 추가하여 JavaScript 애플리케이션으로 리디렉션됩니다. 일반적으로 더 안전하고쿼리를
통해 권장됩니다. -
flow - OpenID Connect 흐름을 설정합니다. 유효한 값은
표준
,암시적
또는하이브리드
입니다. -
enableLogging - Keycloak에서 콘솔까지 로깅 메시지를 활성화합니다(기본값은
false
). pkceMethod - 사용할 Proof Key Code Exchange(PKCE)의 방법입니다. 이 값을 구성하면 PKCE 메커니즘이 활성화됩니다. 사용 가능한 옵션:
- "S256" - SHA256 기반 PKCE 방법
- messageReceiveTimeout - Keycloak 서버의 메시지 응답을 기다리는 동안 시간 초과를 밀리초 단위로 설정합니다. 이는 예를 들어 타사 쿠키 확인 중에 메시지를 기다리는 경우 사용됩니다. 기본값은 10000입니다.
초기화가 완료되면 해결 가능한 명령을 반환합니다.
login(options)
로그인 양식으로 리디렉션합니다.
옵션은 다음과 같은 선택적 오브젝트입니다.
- redirecturi - 로그인 후 리디렉션할 배를 지정합니다.
-
프롬프트 - 이 매개변수를 사용하면 Red Hat Single Sign-On 서버 측의 로그인 흐름을 약간 사용자 지정할 수 있습니다. 예를 들어 로그인 값의 경우 로그인 화면 표시를 강제 적용합니다.
prompt
매개변수의 가능한 모든 값과 세부 사항은 Parameters Forwarding 섹션 을 참조하십시오. -
maxAge - 사용자가 이미 인증된 경우에만 사용됩니다. 사용자 인증이 발생한 이후의 최대 시간을 지정합니다. 사용자가 이미
maxAge
보다 오랜 시간 동안 인증되면 SSO가 무시되고 다시 인증해야 합니다. - loginHint - 로그인 양식에 사용자 이름/이메일 필드를 미리 채우는 데 사용됩니다.
-
범위 - 이 특정 로그인에 대해 다른 값으로
init
에 구성된 범위를 재정의합니다. - idpHint - Red Hat Single Sign-On에 로그인 페이지 표시를 건너뛰고 지정된 ID 공급자로 자동으로 리디렉션하도록 지시하는 데 사용됩니다. ID 공급자 설명서에서 추가 정보 .
-
ACR - 클레임 매개변수 내에 Red Hat Single Sign-On 서버로 전송되는
acr
클레임
에 대한 정보가 포함되어 있습니다. 일반적인 사용은 단계별 인증을 위한 것입니다. 사용의 예: ["silver", "gold"], essential: true }
. 자세한 내용은 OpenID Connect 사양 및 단계별 인증 설명서 를 참조하십시오. -
작업 - 값이
등록
되면 사용자가 등록 페이지로 리디렉션됩니다. 값이UPDATE_PASSWORD
인 경우 사용자는 재설정 암호 페이지로 리디렉션됩니다(인증되지 않은 경우 사용자를 먼저 로그인 페이지로 이동하고 인증 후 리디렉션), 로그인 페이지로 리디렉션됩니다. - locale - OIDC 1.0 사양의 3.1.2.1 섹션에 따라 'ui_locales' 쿼리 매개 변수를 설정합니다.
-
cordovaOptions - Cordova in-app-browser에 전달되는 인수를 지정합니다(해당되는 경우).
숨겨진
옵션과위치는
이러한 인수의 영향을 받지 않습니다. 사용 가능한 모든 옵션은 https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/ 에서 정의됩니다. 사용 예:{ zoom: "no", hardwareback: "yes" }
;
createLoginUrl(options)
URL을 로그인 양식으로 반환합니다.
옵션은 선택적 오브젝트로 기능 로그인
과 동일한 옵션을 지원합니다.
logout(options)
logout으로 리디렉션됩니다.
옵션은 다음과 같은 오브젝트입니다.
- redirecturi - logout 후 리디렉션할 uri를 지정합니다.
createLogoutUrl(options)
URL을 반환하여 사용자를 로그아웃합니다.
옵션은 다음과 같은 오브젝트입니다.
- redirecturi - logout 후 리디렉션할 uri를 지정합니다.
register(options)
등록 양식으로 리디렉션합니다. 옵션 action = 'register'를 사용하여 로그인 바로 가기
로그인 방법과 관련된 옵션은 동일하지만 '작업'은 'register'로 설정됩니다.
createRegisterUrl(options)
URL을 등록 페이지로 되돌립니다. 옵션 action = 'register'를 사용하여 createLoginUrl의 바로 가기
createLoginUrl 메서드와 옵션이 동일하지만 '작업'은 'register'로 설정됩니다.
accountManagement()
계정 관리 콘솔로 리디렉션합니다.
createAccountUrl(options)
URL을 계정 관리 콘솔로 반환합니다.
옵션은 다음과 같은 오브젝트입니다.
- redirecturi - 다시 애플리케이션으로 리디렉션할 때 리디렉션할 uri를 지정합니다.
hasRealmRole(role)
토큰에 지정된 영역 역할이 있는 경우 true를 반환합니다.
hasResourceRole(role, resource)
리소스에 대해 지정된 역할이 있는 경우 토큰에 true를 반환합니다(지정되지 않은 clientId가 사용되는 경우 리소스는 선택 사항입니다).
loadUserProfile()
사용자 프로필을 로드합니다.
프로필로 해결되는 명령을 반환합니다.
예를 들면 다음과 같습니다.
keycloak.loadUserProfile() .then(function(profile) { alert(JSON.stringify(profile, null, " ")) }).catch(function() { alert('Failed to load user profile'); });
keycloak.loadUserProfile()
.then(function(profile) {
alert(JSON.stringify(profile, null, " "))
}).catch(function() {
alert('Failed to load user profile');
});
isTokenExpired(minValidity)
토큰이 만료되기 전에 minValidity초보다 적은 경우 true를 반환합니다(지정 0을 사용하지 않는 경우minValidity는 선택 사항입니다).
updateToken(minValidity)
토큰이 minValidity 초 내에 만료되는 경우(마지어 5를 지정하지 않은 경우minValidity는 선택 사항임) 토큰이 새로 고쳐집니다. -1이 minValidity로 전달되면 토큰이 강제로 새로 고쳐집니다. 세션 상태 iframe이 활성화된 경우 세션 상태도 확인됩니다.
토큰이 새로 고쳐졌는지 여부를 나타내는 부울로 해결되는 명령을 반환합니다.
예를 들면 다음과 같습니다.
keycloak.updateToken(5) .then(function(refreshed) { if (refreshed) { alert('Token was successfully refreshed'); } else { alert('Token is still valid'); } }).catch(function() { alert('Failed to refresh the token, or the session has expired'); });
keycloak.updateToken(5)
.then(function(refreshed) {
if (refreshed) {
alert('Token was successfully refreshed');
} else {
alert('Token is still valid');
}
}).catch(function() {
alert('Failed to refresh the token, or the session has expired');
});
clearToken()
토큰을 포함한 인증 상태 지웁니다. 이는 애플리케이션이 세션을 감지한 경우(예: 토큰 업데이트 실패 시) 유용할 수 있습니다.
이를 호출하면 onAuthLogout 콜백 리스너가 호출됩니다.
2.2.7.4. 콜백 이벤트
어댑터는 특정 이벤트에 대한 콜백 리스너 설정을 지원합니다. init
함수를 호출하기 전에 이러한 값을 설정해야 합니다.
예를 들면 다음과 같습니다.
keycloak.onAuthSuccess = function() { alert('authenticated'); }
keycloak.onAuthSuccess = function() { alert('authenticated'); }
사용 가능한 이벤트는 다음과 같습니다.
- onReady(authenticated) - 어댑터가 초기화될 때 호출됩니다.
- OnAuthSuccess - 사용자가 성공적으로 인증될 때 호출됩니다.
- OnAuthError - 인증 중에 오류가 발생한 경우 called.
- OnAuthRefreshSuccess - 토큰을 새로 고칠 때 호출됩니다.
- onAuthRefreshError - 토큰을 새로 고치는 동안 오류가 있는 경우 호출됨.
- onAuthLogout - 사용자가 로그아웃된 경우 호출됨(세션 상태 iframe이 활성화되거나 Cordova 모드에서만 호출됨).
- OnTokenExpired - 액세스 토큰이 만료될 때 호출됩니다. 새로 고침 토큰을 사용할 수 있는 경우 updateToken을 사용하여 토큰을 새로 고치거나 (즉 암시적 흐름이 있는 경우) 로그인 화면으로 리디렉션하여 새 액세스 토큰을 가져올 수 있습니다.
2.3. Node.js 어댑터
Red Hat Single Sign-On은 서버 측 JavaScript 애플리케이션을 보호하기 위해 Connect 에 구축된 Node.js 어댑터를 제공합니다. 이 목표는 Express.js 와 같은 프레임워크와 통합할 수 있을 만큼 유연해야 했습니다.
Node.js 어댑터를 사용하려면 먼저 Red Hat Single Sign-On 관리 콘솔에서 애플리케이션의 클라이언트를 생성해야 합니다. 어댑터는 공용, 기밀, 전달자 전용 액세스 유형을 지원합니다. 선택할 수 있는 항목은 사용 사례에 따라 다릅니다.
클라이언트가 생성되면 설치
탭을 클릭하고 형식 옵션
용으로 Red Hat Single Sign-On OIDC JSON
을 선택한 다음 다운로드를
클릭합니다. 다운로드한 keycloak.json
파일은 프로젝트의 루트 폴더에 있어야 합니다.
2.3.1. 설치
Node.js 를 이미 설치했다고 가정하면 애플리케이션의 폴더를 생성합니다.
mkdir myapp && cd myapp
mkdir myapp && cd myapp
npm init
명령을 사용하여 애플리케이션에 대한 package.json
을 생성합니다. 이제 종속 항목 목록에 Red Hat Single Sign-On 연결 어댑터를 추가합니다.
"dependencies": { "keycloak-connect": "file:keycloak-connect-18.0.7.tgz" }
"dependencies": {
"keycloak-connect": "file:keycloak-connect-18.0.7.tgz"
}
2.3.2. 사용법
- Keycloak 클래스 인스턴스화
-
Keycloak
클래스는 애플리케이션과 구성 및 통합을 위한 중앙 지점을 제공합니다. 가장 간단한 생성에는 인수가 포함되지 않습니다.
프로젝트의 루트 디렉터리에서 server.js
라는 파일을 생성하고 다음 코드를 추가합니다.
const session = require('express-session'); const Keycloak = require('keycloak-connect'); const memoryStore = new session.MemoryStore(); const keycloak = new Keycloak({ store: memoryStore });
const session = require('express-session');
const Keycloak = require('keycloak-connect');
const memoryStore = new session.MemoryStore();
const keycloak = new Keycloak({ store: memoryStore });
express-session
종속성을 설치합니다.
npm install express-session
npm install express-session
server.js
스크립트를 시작하려면 package.json
의 'scripts' 섹션에 다음 명령을 추가합니다.
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start" "node server.js" },
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start" "node server.js"
},
이제 다음 명령을 사용하여 서버를 실행할 수 있습니다.
npm run start
npm run start
기본적으로 이 명령은 애플리케이션의 기본 실행 파일과 함께 keycloak.json
이라는 파일을 찾고 루트 폴더의 경우 공개 키, 영역 이름, 다양한 URL과 같은 키클로크별 설정을 초기화합니다.
이 경우 Keycloak 관리 콘솔에 액세스하려면 Keycloak 배포가 필요합니다.
Podman 또는 Docker를 사용하여 Keycloak 관리 콘솔을 배포하는 방법에 대한 링크를 방문하십시오.
이제 Red Hat Single Sign-On 관리 콘솔 → 클라이언트(left sidebar) → 클라이언트 → 설치 → 형식 옵션 → Keycloak OIDC JSON을 선택하여 keycloak.json
파일을 가져올 준비가 되었습니다.
다운로드한 파일을 프로젝트의 루트 폴더에 붙여넣습니다.
이 방법을 사용하면 적절한 기본값이 모두 사용됩니다. 또는 keycloak.json
파일 대신 구성 오브젝트를 제공할 수도 있습니다.
const kcConfig = { clientId: 'myclient', bearerOnly: true, serverUrl: 'http://localhost:8080/auth', realm: 'myrealm', realmPublicKey: 'MIIBIjANB...' }; const keycloak = new Keycloak({ store: memoryStore }, kcConfig);
const kcConfig = {
clientId: 'myclient',
bearerOnly: true,
serverUrl: 'http://localhost:8080/auth',
realm: 'myrealm',
realmPublicKey: 'MIIBIjANB...'
};
const keycloak = new Keycloak({ store: memoryStore }, kcConfig);
애플리케이션은 다음을 사용하여 사용자를 선호하는 ID 공급자로 리디렉션할 수도 있습니다.
const keycloak = new Keycloak({ store: memoryStore, idpHint: myIdP }, kcConfig);
const keycloak = new Keycloak({ store: memoryStore, idpHint: myIdP }, kcConfig);
- 웹 세션 저장소 구성
-
웹 세션을 사용하여 인증을 위해 서버 측 상태를 관리하려면 최소
store
매개변수로Keycloak(…)
을 초기화하고express-session
이 사용되는 실제 세션 저장소를 전달해야 합니다.
const session = require('express-session'); const memoryStore = new session.MemoryStore(); // Configure session app.use( session({ secret: 'mySecret', resave: false, saveUninitialized: true, store: memoryStore, }) ); const keycloak = new Keycloak({ store: memoryStore });
const session = require('express-session');
const memoryStore = new session.MemoryStore();
// Configure session
app.use(
session({
secret: 'mySecret',
resave: false,
saveUninitialized: true,
store: memoryStore,
})
);
const keycloak = new Keycloak({ store: memoryStore });
- 사용자 정의 범위 값 전달
-
기본적으로 범위 값
openid
는 Red Hat Single Sign-On의 로그인 URL에 쿼리 매개변수로 전달되지만 사용자 지정 값을 추가할 수 있습니다.
const keycloak = new Keycloak({ scope: 'offline_access' });
const keycloak = new Keycloak({ scope: 'offline_access' });
2.3.3. 미들웨어 설치
인스턴스화한 후 연결 가능 앱에 미들웨어를 설치합니다.Once instantiated, install the middleware into your connect-able app:
이렇게 하려면 먼저 Express를 설치해야 합니다.
npm install express
npm install express
아래에 설명된 대로 프로젝트에 Express가 필요합니다.
const express = require('express'); const app = express();
const express = require('express');
const app = express();
아래 코드에 추가하여 Express에서 Keycloak 미들웨어를 구성합니다.
app.use( keycloak.middleware() );
app.use( keycloak.middleware() );
마지막으로 다음 코드를 main.js
에 추가하여 포트 3000에서 HTTP 요청을 수신하도록 서버를 설정해 보겠습니다.
app.listen(3000, function () { console.log('App listening on port 3000'); });
app.listen(3000, function () {
console.log('App listening on port 3000');
});
2.3.4. 프록시 구성
애플리케이션이 SSL 연결 Express를 종료하는 프록시 뒤에서 실행중인 경우 프록시 뒤의 표현 가이드에 따라 SSL 연결을 구성해야 합니다. 잘못된 프록시 설정을 사용하면 잘못된 리디렉션 URI가 생성될 수 있습니다.
설정 예:
const app = express(); app.set( 'trust proxy', true ); app.use( keycloak.middleware() );
const app = express();
app.set( 'trust proxy', true );
app.use( keycloak.middleware() );
2.3.5. 인증 확인
리소스에 액세스하기 전에 사용자가 인증되었는지 확인하려면 keycloak.checkSso()
를 사용합니다. 이는 사용자가 이미 로그인한 경우에만 인증됩니다. 사용자가 로그인하지 않은 경우 브라우저가 원래 요청된 URL로 다시 리디렉션되고 인증되지 않은 상태로 유지됩니다.
app.get( '/check-sso', keycloak.checkSso(), checkSsoHandler );
app.get( '/check-sso', keycloak.checkSso(), checkSsoHandler );
2.3.6. 리소스 보호
- 간단한 인증
-
리소스에 액세스하기 전에 사용자를 인증해야 하는 것을 강제 적용하려면
keycloak.protect()
의 인수 없음 버전을 사용하십시오.
app.get( '/complain', keycloak.protect(), complaintHandler );
app.get( '/complain', keycloak.protect(), complaintHandler );
- 역할 기반 권한 부여
- 현재 앱의 애플리케이션 역할로 리소스를 보호하려면 다음을 수행합니다.
app.get( '/special', keycloak.protect('special'), specialHandler );
app.get( '/special', keycloak.protect('special'), specialHandler );
다른 앱의 애플리케이션 역할로 리소스를 보호하려면 다음을 수행합니다.
app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler );
app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler );
영역 역할을 사용하여 리소스를 보호하려면 다음을 수행합니다.
app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
- 리소스 기반 권한 부여
-
리소스 기반 권한 부여를 사용하면 Keycloak에 정의된 정책 세트를 기반으로 리소스를 보호하고 특정 메서드/작업,** *를 사용하여 애플리케이션에서 권한을 외부화할 수 있습니다. 이를 위해 리소스를 보호하는 데 사용할 수 있는
keycloak.enforcer
메서드를 노출합니다.*
app.get('/apis/me', keycloak.enforcer('user:profile'), userProfileHandler);
app.get('/apis/me', keycloak.enforcer('user:profile'), userProfileHandler);
keycloak-enforcer
방법은 response_mode
구성 옵션의 값에 따라 두 가지 모드에서 작동합니다.
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), userProfileHandler);
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), userProfileHandler);
response_mode
가 토큰
으로 설정된 경우 애플리케이션에 전송된 전달자 토큰이 나타내는 주체를 대신하여 권한을 서버에서 가져옵니다. 이 경우 서버가 부여한 권한으로 Keycloak에서 새 액세스 토큰을 발행합니다. 서버가 예상 권한으로 토큰을 사용하여 응답하지 않으면 요청이 거부됩니다. 이 모드를 사용하는 경우 다음과 같이 요청에서 토큰을 가져올 수 있습니다.
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), function (req, res) { const token = req.kauth.grant.access_token.content; const permissions = token.authorization ? token.authorization.permissions : undefined; // show user profile });
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), function (req, res) {
const token = req.kauth.grant.access_token.content;
const permissions = token.authorization ? token.authorization.permissions : undefined;
// show user profile
});
애플리케이션이 세션을 사용하고 있고 서버의 이전 결정을 캐시하고 새로 고침 토큰을 자동으로 처리하려는 경우 이 모드를 선호합니다. 이 모드는 클라이언트 및 리소스 서버 역할을 하는 애플리케이션에 특히 유용합니다.
response_mode
가 권한
(기본 모드)로 설정된 경우 서버는 새 액세스 토큰을 발행하지 않고 부여된 권한 목록만 반환합니다. 새 토큰을 발행하지 않는 것 외에도 이 방법은 다음과 같이 요청을
통해 서버에서 부여한 권한을 노출합니다.
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'permissions'}), function (req, res) { const permissions = req.permissions; // show user profile });
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'permissions'}), function (req, res) {
const permissions = req.permissions;
// show user profile
});
사용 중인 response_mode
에 관계없이 keycloak.enforcer
방법은 먼저 애플리케이션에 전송된 전달자 토큰 내의 권한을 확인하려고 합니다. 전달자 토큰이 이미 예상 권한을 전달한 경우 결정을 받기 위해 서버와 상호 작용할 필요가 없습니다. 이 기능은 클라이언트가 보안 리소스에 액세스하기 전에 예상 권한으로 서버에서 액세스 토큰을 가져올 수 있으므로 증분 권한과 같은 Keycloak 인증 서비스에서 제공하는 일부 기능을 사용할 수 있고 keycloak.enforcer
가 리소스에 대한 액세스를 적용하는 경우 서버에 대한 추가 요청을 방지할 수 있는 경우에 특히 유용합니다.
기본적으로 정책 적용자는 애플리케이션에 정의된 client_id
를 사용합니다(예: keycloak.json
)을 통해 Keycloak 인증 서비스를 지원하는 Keycloak의 클라이언트를 참조합니다. 이 경우 실제로 리소스 서버인 경우 클라이언트를 공용으로 제공할 수 없습니다.
애플리케이션이 공용 클라이언트(frontend) 및 리소스 서버(backend) 둘 다 역할을 하는 경우 다음 구성을 사용하여 적용하려는 정책과 함께 Keycloak의 다른 클라이언트를 참조할 수 있습니다.
keycloak.enforcer('user:profile', {resource_server_id: 'my-apiserver'})
keycloak.enforcer('user:profile', {resource_server_id: 'my-apiserver'})
Keycloak에서 다른 클라이언트를 사용하여 프런트 엔드 및 백엔드를 나타내는 것이 좋습니다.
Keycloak 인증 서비스를 사용하여 보호하는 애플리케이션이 활성화되어 있고 keycloak.json
에 클라이언트 인증 정보가 정의된 경우 추가 클레임을 서버에 푸시하고 정책에서 해당 정보를 정책에서 사용할 수 있도록 할 수 있습니다. 이를 위해 푸시하려는 클레임
과 함께 JSON을 반환하는 함수
를 예상하는 클레임 구성 옵션을 정의할 수 있습니다.
app.get('/protected/resource', keycloak.enforcer(['resource:view', 'resource:write'], { claims: function(request) { return { "http.uri": ["/protected/resource"], "user.agent": // get user agent from request } } }), function (req, res) { // access granted
app.get('/protected/resource', keycloak.enforcer(['resource:view', 'resource:write'], {
claims: function(request) {
return {
"http.uri": ["/protected/resource"],
"user.agent": // get user agent from request
}
}
}), function (req, res) {
// access granted
애플리케이션 리소스를 보호하기 위해 Keycloak을 구성하는 방법에 대한 자세한 내용은 인증 서비스 가이드를 참조하십시오.
- 고급 권한 부여
- URL 자체의 일부를 기반으로 리소스를 보호하려면 각 섹션에 대한 역할이 있다고 가정합니다.
function protectBySection(token, request) { return token.hasRole( request.params.section ); } app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );
function protectBySection(token, request) {
return token.hasRole( request.params.section );
}
app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );
고급 로그인 설정:
기본적으로 권한이 없는 모든 요청은 클라이언트가 전달하지 않는 한 Red Hat Single Sign-On 로그인 페이지로 리디렉션됩니다. 그러나 기밀 또는 공용 클라이언트는 검색 가능한 API 끝점을 모두 호스팅할 수 있습니다. 인증되지 않은 API 요청에서 리디렉션을 방지하고 대신 HTTP 401을 반환하려면 redirectToLogin 함수를 덮어쓸 수 있습니다.
예를 들어, 이 덮어쓰기는 URL에 /api/가 포함되어 있는지 확인하고 로그인 리디렉션을 비활성화합니다.
Keycloak.prototype.redirectToLogin = function(req) { const apiReqMatcher = /\/api\//i; return !apiReqMatcher.test(req.originalUrl || req.url); };
Keycloak.prototype.redirectToLogin = function(req) {
const apiReqMatcher = /\/api\//i;
return !apiReqMatcher.test(req.originalUrl || req.url);
};
2.3.7. 추가 URL
- 명시적 사용자 트리거된 로그아웃
-
기본적으로 미들웨어는
/logout
에 대한 호출을 따라 Red Hat Single Sign-On-centric 로그아웃 워크플로를 통해 사용자를 전송합니다. 이 설정은logout
구성 매개변수를middleware()
호출에 지정하여 변경할 수 있습니다.
app.use( keycloak.middleware( { logout: '/logoff' } ));
app.use( keycloak.middleware( { logout: '/logoff' } ));
user-triggered logout이 쿼리 매개변수 redirect_url
을 호출하면 다음을 전달할 수 있습니다.
https://example.com/logoff?redirect_url=https%3A%2F%2Fexample.com%3A3000%2Flogged%2Fout
https://example.com/logoff?redirect_url=https%3A%2F%2Fexample.com%3A3000%2Flogged%2Fout
이 매개변수는 OIDC 로그 아웃 끝점의 리디렉션 URL로 사용되며 사용자는 https://example.com/logged/out
로 리디렉션됩니다.
- Red Hat Single Sign-On 관리자 콜백
-
또한 미들웨어는 Red Hat Single Sign-On 콘솔의 콜백을 지원하여 단일 세션 또는 모든 세션을 로그아웃합니다. 기본적으로 이러한 유형의 관리 콜백은
/
의 루트 URL에 대해 발생하지만middleware()
호출에admin
매개변수를 제공하여 변경할 수 있습니다.
app.use( keycloak.middleware( { admin: '/callbacks' } );
app.use( keycloak.middleware( { admin: '/callbacks' } );
2.3.8. 완료 예
Node.js 어댑터 사용을 사용하는 전체 예제는 Node.js 용 Keycloak 빠른 시작에서 확인할 수 있습니다.
2.4. 기타 OpenID Connect 라이브러리
Red Hat Single Sign-On은 일반적으로 사용하기 쉽고 Red Hat Single Sign-On과의 통합을 보다 쉽게 제공하는 제공된 어댑터로 보호할 수 있습니다. 그러나 프로그래밍 언어, 프레임워크 또는 플랫폼에서 어댑터를 사용할 수 없는 경우 일반 OpenID Connect Relying Party(RP) 라이브러리를 대신 사용하도록 선택할 수 있습니다. 이 장에서는 Red Hat Single Sign-On 관련 세부 사항에 대해 설명하고 특정 프로토콜 세부 정보는 포함하지 않습니다. 자세한 내용은 OpenID Connect 사양 및 OAuth2 사양 을 참조하십시오.
2.4.1. endpoints
이해해야 할 가장 중요한 끝점은 잘 알려진
구성 끝점입니다. Red Hat Single Sign-On의 OpenID Connect 구현과 관련된 끝점 및 기타 구성 옵션이 나열됩니다. 끝점은 다음과 같습니다.
/realms/{realm-name}/.well-known/openid-configuration
/realms/{realm-name}/.well-known/openid-configuration
전체 URL을 얻으려면 Red Hat Single Sign-On의 기본 URL을 추가하고 {realm-name}
을 영역 이름으로 교체합니다. 예를 들면 다음과 같습니다.
http://localhost:8080/auth/realms/master/.well-known/openid-configuration
일부 RP 라이브러리는 이 끝점에서 필요한 모든 끝점을 검색하지만, 다른 라이브러리에서는 끝점을 개별적으로 나열해야 할 수도 있습니다.
2.4.1.1. 권한 부여 끝점
/realms/{realm-name}/protocol/openid-connect/auth
/realms/{realm-name}/protocol/openid-connect/auth
권한 부여 끝점은 최종 사용자의 인증을 수행합니다. 이 작업은 사용자 에이전트를 이 엔드포인트로 리디렉션하여 수행됩니다.
자세한 내용은 OpenID Connect 사양의 Authorization Endpoint 섹션을 참조하십시오.
2.4.1.2. 토큰 끝점
/realms/{realm-name}/protocol/openid-connect/token
/realms/{realm-name}/protocol/openid-connect/token
토큰 끝점은 토큰을 가져오는 데 사용됩니다. 토큰은 권한 부여 코드를 교환하거나 사용되는 흐름에 따라 인증 정보를 직접 제공하여 얻을 수 있습니다. 토큰 엔드포인트는 만료 시 새 액세스 토큰을 가져오는 데도 사용됩니다.
자세한 내용은 OpenID Connect 사양 의 토큰 엔드 포인트 섹션을 참조하십시오.
2.4.1.3. userinfo 끝점
/realms/{realm-name}/protocol/openid-connect/userinfo
/realms/{realm-name}/protocol/openid-connect/userinfo
userinfo 끝점은 인증된 사용자에 대한 표준 클레임을 반환하고 전달자 토큰으로 보호됩니다.
자세한 내용은 OpenID Connect 사양의 Userinfo Endpoint 섹션을 참조하십시오.
2.4.1.4. logout 끝점
/realms/{realm-name}/protocol/openid-connect/logout
/realms/{realm-name}/protocol/openid-connect/logout
logout 끝점은 인증된 사용자를 로그아웃합니다.
사용자 에이전트는 엔드포인트로 리디렉션될 수 있으며, 이 경우 활성 사용자 세션이 로그아웃됩니다. 그런 다음 사용자 에이전트가 다시 애플리케이션으로 리디렉션됩니다.
끝점은 애플리케이션에서 직접 호출할 수도 있습니다. 이 엔드포인트를 직접 호출하려면 새로 고침 토큰과 클라이언트를 인증하는 데 필요한 자격 증명을 포함해야 합니다.
2.4.1.5. 인증서 끝점
/realms/{realm-name}/protocol/openid-connect/certs
/realms/{realm-name}/protocol/openid-connect/certs
인증서 끝점은 JSON Web Key(JWK)로 인코딩된 영역에서 활성화한 공개 키를 반환합니다. 영역 설정에 따라 토큰을 검증하기 위해 하나 이상의 키가 활성화될 수 있습니다. 자세한 내용은 Server Administration Guide 및 JSON Web Key 사양 을 참조하십시오.
2.4.1.6. 인트로스펙션 끝점
/realms/{realm-name}/protocol/openid-connect/token/introspect
/realms/{realm-name}/protocol/openid-connect/token/introspect
인트로스펙션 끝점은 토큰의 활성 상태를 검색하는 데 사용됩니다. 즉, 이를 사용하여 액세스 또는 새로 고침 토큰의 유효성을 검사할 수 있습니다. 이는 기밀 고객만 호출할 수 있습니다.
이 끝점에서 호출하는 방법에 대한 자세한 내용은 OAuth 2.0 토큰 인트로스펙션 사양을 참조하십시오.
2.4.1.7. 동적 클라이언트 등록 끝점
/realms/{realm-name}/clients-registrations/openid-connect
/realms/{realm-name}/clients-registrations/openid-connect
동적 클라이언트 등록 끝점은 클라이언트를 동적으로 등록하는 데 사용됩니다.
자세한 내용은 클라이언트 등록 장 및 OpenID Connect 동적 클라이언트 등록 사양에서 참조하십시오.
2.4.1.8. 토큰 해지 끝점
/realms/{realm-name}/protocol/openid-connect/revoke
/realms/{realm-name}/protocol/openid-connect/revoke
토큰 해지 끝점은 토큰을 취소하는 데 사용됩니다. 이 끝점에서는 새로 고침 토큰과 액세스 토큰을 모두 지원합니다.
이 끝점에서 호출하는 방법에 대한 자세한 내용은 OAuth 2.0 토큰 해지 사양 을 참조하십시오.
2.4.1.9. 장치 인증 끝점
/realms/{realm-name}/protocol/openid-connect/auth/device
/realms/{realm-name}/protocol/openid-connect/auth/device
장치 인증 끝점은 장치 코드와 사용자 코드를 가져오는 데 사용됩니다. 이는 기밀 또는 공용 클라이언트에서 호출할 수 있습니다.
이 끝점에서 호출하는 방법에 대한 자세한 내용은 OAuth 2.0 장치 권한 부여 사양 을 참조하십시오.
2.4.1.10. Backchannel Authentication 끝점
/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth
/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth
백채널 인증 끝점은 클라이언트가 만든 인증 요청을 식별하는 auth_req_id를 가져오는 데 사용됩니다. 이는 기밀 고객만 호출할 수 있습니다.
이 끝점에서 호출하는 방법에 대한 자세한 내용은 OpenID Connect Client Initiated Backchannel Authentication Flow 사양 을 참조하십시오.
또한 이 가이드의 Client Initiated Backchannel Authentication Grant 섹션 및 Server Administration Guide의 Client Initiated Backchannel Authentication Grant 섹션 과 같은 Red Hat Single Sign-On 설명서의 다른 위치를 참조하십시오. https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html-single/server_administration_guide/#_client_initiated_backchannel_authentication_grant
2.4.2. 액세스 토큰 검증
Red Hat Single Sign-On에서 발행한 액세스 토큰을 수동으로 검증해야 하는 경우 Introspection Endpoint 를 호출할 수 있습니다. 이 접근 방식의 단점은 Red Hat Single Sign-On 서버를 네트워크를 호출해야 한다는 점입니다. 이 작업은 속도가 느리고 동시에 너무 많은 유효성 검사 요청이 있는 경우 서버에 과부하가 발생할 수 있습니다. Red Hat Single Sign-On 발행 액세스 토큰은 JSON 웹 서명 (JWS)을 사용하여 디지털 서명 및 인코딩되는 JSON 웹 토큰 입니다. 이러한 방식으로 인코딩되므로 발급 영역의 공개 키를 사용하여 로컬에서 액세스 토큰의 유효성을 확인할 수 있습니다. 검증 코드에서 영역의 공개 키를 하드 코딩하거나 JWS 내에 포함된 KID(Key ID)를 사용하여 인증서 끝점 을 사용하여 공개 키를 조회하고 캐시할 수 있습니다. 코드화된 언어에 따라 JWS 검증에 도움이 될 수 있는 다양한 타사 라이브러리가 있습니다.
2.4.3. flows
2.4.3.1. 허가 코드
권한 부여 코드 흐름은 사용자 에이전트를 Red Hat Single Sign-On으로 리디렉션합니다. 사용자가 Red Hat Single Sign-On으로 성공적으로 인증되면 인증 코드가 생성되고 사용자 에이전트가 다시 애플리케이션으로 리디렉션됩니다. 그러면 애플리케이션에서 인증 정보와 함께 권한 부여 코드를 사용하여 Red Hat Single Sign-On에서 액세스 토큰, 새로 고침 토큰 및 ID 토큰을 가져옵니다.
이 흐름은 웹 애플리케이션을 대상으로 하지만 사용자 에이전트를 포함할 수 있는 모바일 애플리케이션을 비롯한 네이티브 애플리케이션에도 권장됩니다.
자세한 내용은 OpenID Connect 사양의 인증 코드 흐름을 참조하십시오.
2.4.3.2. 암시적
Implicit flow 리디렉션은 인증 코드 흐름과 유사하게 작동하지만 인증 코드를 반환하는 대신 액세스 토큰 및 ID 토큰이 반환됩니다. 이렇게 하면 추가 호출이 액세스 토큰의 인증 코드를 교환할 필요가 줄어듭니다. 그러나 새로 고침 토큰은 포함되지 않습니다. 이로 인해 만료 기간이 긴 액세스 토큰을 허용해야 하는데, 이는 이러한 토큰을 무효화하기가 매우 어렵기 때문입니다. 또는 초기 액세스 토큰이 만료된 후 새 액세스 토큰을 얻으려면 새 리디렉션이 필요합니다. Implicit 흐름은 애플리케이션이 사용자를 인증하고 로그 아웃 자체를 처리하려는 경우에만 유용합니다.
액세스 토큰과 권한 부여 코드가 모두 반환되는 하이브리드 흐름도 있습니다.
한 가지 유의할 점은 Implicit 흐름과 하이브리드 흐름 모두 웹 서버 로그 및 브라우저 기록을 통해 액세스 토큰이 유출될 수 있으므로 잠재적인 보안 위험이 있다는 것입니다. 이는 액세스 토큰의 단기 만료를 사용하여 다소 완화됩니다.
자세한 내용은 OpenID Connect 사양의 Implicit Flow 를 참조하십시오.
2.4.3.3. 리소스 소유자 암호 자격 증명
리소스 소유자 암호 자격 증명(Red Hat Single Sign-On에서 직접 부여)이라고 하는 경우 토큰에 대한 사용자 자격 증명을 교환할 수 있습니다. 따라서 반드시 필요한 경우를 제외하고 이 흐름을 사용하지 않는 것이 좋습니다. 이 기능이 유용할 수 있는 예는 레거시 애플리케이션 및 명령줄 인터페이스입니다.
이 흐름 사용에는 다음과 같은 제한 사항이 있습니다.
- 사용자 인증 정보가 애플리케이션에 노출됨
- 애플리케이션은 로그인 페이지가 필요합니다.
- 애플리케이션은 인증 스키마를 알고 있어야 합니다.
- 인증 흐름을 변경하려면 애플리케이션을 변경해야 합니다.
- ID 브로커 또는 소셜 로그인에 대한 지원 없음
- flows are not supported (user self-registration, required actions, etc.)
클라이언트가 리소스 소유자 암호 자격 증명을 사용하도록 허용하려면 클라이언트에 Direct Access Grants Enabled
옵션이 활성화되어 있어야 합니다.
이 흐름은 OpenID Connect에 포함되어 있지 않지만 OAuth 2.0 사양의 일부입니다.
자세한 내용은 OAuth 2.0 사양의 Resource Owner Password Credentials Grant 장을 참조하십시오.
2.4.3.3.1. CURL 사용 예
다음 예제에서는 사용자 이름 사용자 및 암호
를 사용하여 영역 마스터
에 있는 사용자에 대한 액세스 토큰을 가져오는 방법을 보여줍니다. 이 예제에서는 기밀 클라이언트
myclient
를 사용합니다.
curl \ -d "client_id=myclient" \ -d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \ -d "username=user" \ -d "password=password" \ -d "grant_type=password" \ "http://localhost:8080/auth/realms/master/protocol/openid-connect/token"
curl \
-d "client_id=myclient" \
-d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
-d "username=user" \
-d "password=password" \
-d "grant_type=password" \
"http://localhost:8080/auth/realms/master/protocol/openid-connect/token"
2.4.3.4. 클라이언트 인증 정보
클라이언트 자격 증명은 클라이언트(애플리케이션 및 서비스)가 사용자를 대신하여 대신 자체적으로 액세스하려는 경우 사용됩니다. 예를 들어 특정 사용자가 아닌 일반적인 시스템에 변경 사항을 적용하는 백그라운드 서비스에 유용할 수 있습니다.
Red Hat Single Sign-On은 클라이언트가 시크릿 또는 공개/개인 키를 사용하여 인증할 수 있도록 지원합니다.
이 흐름은 OpenID Connect에 포함되어 있지 않지만 OAuth 2.0 사양의 일부입니다.
자세한 내용은 OAuth 2.0 사양의 클라이언트 자격 증명 부여 장을 참조하십시오.
2.4.3.5. 장치 권한 부여 권한
장치 권한 부여는 입력 기능이 제한되거나 적절한 브라우저가 없는 인터넷에 연결된 장치에서 실행되는 클라이언트가 사용합니다. 애플리케이션은 Red Hat Single Sign-On 장치 코드와 사용자 코드를 요청합니다. Red Hat Single Sign-On은 장치 코드와 사용자 코드를 생성합니다. Red Hat Single Sign-On은 장치 코드 및 사용자 코드를 애플리케이션에 대한 응답을 반환합니다. 그런 다음 애플리케이션은 사용자에게 사용자 코드 및 확인 URI를 제공합니다. 사용자는 다른 브라우저를 사용하여 인증할 확인 URI에 액세스합니다. 이 애플리케이션은 Red Hat Single Sign-On이 사용자 승인을 완료할 때까지 Red Hat Single Sign-On을 반복적으로 폴링합니다. 사용자 인증이 완료되면 애플리케이션에서 장치 코드를 가져옵니다. 그런 다음 애플리케이션은 자격 증명과 함께 장치 코드를 사용하여 Red Hat Single Sign-On에서 액세스 토큰, 새로 고침 토큰 및 ID 토큰을 가져옵니다.
자세한 내용은 OAuth 2.0 장치 권한 부여 사양 을 참조하십시오.
2.4.3.6. 클라이언트 시작 백엔드 채널 인증 권한
클라이언트 초기화 백채널 인증 권한은 OAuth 2.0의 권한 부여 코드 부여와 같은 사용자 브라우저를 통해 리디렉션하지 않고 OpenID 공급자와 직접 통신하여 인증 흐름을 시작하려는 클라이언트가 사용합니다.
클라이언트는 클라이언트가 만든 인증 요청을 식별하는 auth_req_id를 Red Hat Single Sign-On을 요청합니다. Red Hat Single Sign-On은 auth_req_id를 생성합니다.
이 auth_req_id를 수신한 후 이 클라이언트는 auth_req_id에 대해 반환하여 액세스 토큰, 새로 고침 토큰 및 ID 토큰을 받기 위해 Red Hat Single Sign-On을 반복적으로 폴링해야 합니다.
클라이언트가 ping
모드를 사용하는 경우 토큰 끝점을 반복적으로 폴링할 필요는 없지만 Red Hat Single Sign-On에서 지정된 클라이언트 알림 끝점으로 전송된 알림을 기다릴 수 있습니다. 클라이언트 알림 엔드포인트는 Red Hat Single Sign-On 관리 콘솔에서 구성할 수 있습니다. 클라이언트 알림 엔드 포인트 계약의 자세한 내용은 CIBA 사양에 설명되어 있습니다.
자세한 내용은 OpenID Connect Client Initiated Backchannel Authentication Flow 사양 을 참조하십시오.
또한 이 가이드의 Backchannel Authentication Endpoint 및 Server Administration Guide의 Client Initiated Backchannel Authentication Grant 섹션 과 같은 Red Hat Single Sign-On 설명서의 다른 위치를 참조하십시오. FAPI CIBA 컴플라이언스에 대한 자세한 내용은 이 가이드의 FAPI 섹션을 참조하십시오.
2.4.4. URI 리디렉션
리디렉션 기반 흐름을 사용하는 경우 클라이언트에 유효한 리디렉션 배리를 사용하는 것이 중요합니다. 리디렉션 배지는 가능한 한 구체적으로 배치해야합니다. 이는 특히 클라이언트 측(공용 클라이언트) 애플리케이션에 적용됩니다. 이렇게 하지 않으면 다음이 발생할 수 있습니다.
- Open redirects - 공격자가 귀하의 도메인에서 발생하는 것처럼 보이는 링크를 스푸핑할 수 있습니다.
- 인증되지 않은 항목 - 사용자가 Red Hat Single Sign-On으로 이미 인증된 경우 공격자는 사용자 지식 없이 사용자를 리디렉션하여 액세스 권한을 얻기 위해 리디렉션을 올바르게 설정하지 않은 공용 클라이언트를 사용할 수 있습니다.
프로덕션 환경에서 웹 애플리케이션의 경우 모든 리디렉션 URI에 항상 https
를 사용합니다. http로 리디렉션을 허용하지 마십시오.
다음과 같은 몇 가지 특수 리디렉션 URI도 있습니다.
http://localhost
- 이 리디렉션 URI는 네이티브 애플리케이션에 유용하며 네이티브 애플리케이션에서 권한 부여 코드를 가져오는 데 사용할 수 있는 임의의 포트에 웹 서버를 생성할 수 있습니다. 이 리디렉션 uri는 모든 포트를 허용합니다.
urn:ietf:wg:oauth:2.0:oob
-
클라이언트에서 웹 서버를 시작할 수 없는 경우(또는 브라우저를 사용할 수 없음) 특수
urn:ietf:wg:oauth:2.0:oob
리디렉션 uri를 사용할 수 있습니다. 이 리디렉션 uri를 사용하는 경우 Red Hat Single Sign-On은 제목과 페이지의 상자에 코드가 포함된 페이지를 표시합니다. 애플리케이션은 브라우저 제목이 변경되었는지 감지하거나 사용자가 코드를 애플리케이션에 수동으로 복사/붙일 수 있습니다. 이 리디렉션 uri를 사용하면 사용자가 다른 장치를 사용하여 애플리케이션에 다시 붙여넣을 코드를 가져올 수도 있습니다.
2.5. FAPI(Financial-grade API) 지원
Red Hat Single Sign-On을 사용하면 관리자가 클라이언트가 다음 사양을 준수하는지 쉽게 확인할 수 있습니다.
이 규정 준수는 Red Hat Single Sign-On 서버에서 사양에 언급된 권한 부여 서버의 요구 사항을 확인합니다. Red Hat Single Sign-On 어댑터는 FAPI에 대한 구체적인 지원이 없으므로 클라이언트(애플리케이션) 측에서 필요한 검증을 수동으로 또는 기타 타사 솔루션을 통해 수행해야 할 수도 있습니다.
2.5.1. FAPI 클라이언트 프로필
클라이언트가 FAPI 준수 여부를 확인하기 위해 서버 관리 가이드에 설명된 대로 해당 영역에서 클라이언트 정책을 구성하고 각 영역에서 자동으로 사용할 수 있는 FAPI 지원을 위해 글로벌 클라이언트 프로필에 연결할 수 있습니다. 클라이언트가 준수하는 데 필요한 FAPI 프로파일을 기반으로 fapi-1-baseline
또는 fapi-1-advanced
프로필을 사용할 수 있습니다.
푸시된 권한 부여 요청(PAR) 을 사용하려면 클라이언트가 fapi-1-baseline
프로필과 PAR 요청에 fapi-1-advanced
를 모두 사용하는 것이 좋습니다. 특히 fapi-1-baseline
프로필에는 pkce-enforcer
executor가 포함되어 있어 클라이언트가 보안 S256 알고리즘과 함께 PKCE를 사용하도록 합니다. PAR 요청을 사용하지 않는 한 FAPI Advanced 클라이언트에는 이 작업이 필요하지 않습니다.
FAPI 호환 방식으로 CIBA 를 사용하려는 경우 클라이언트가 fapi-1-advanced
및 fapi-ciba
클라이언트 프로필을 둘 다 사용하는지 확인하십시오. fapi-ciba
프로필에는 CIBA별 executors 만 포함되어 있으므로 요청된 executor가 포함된 fapi-1-advanced
프로필 또는 요청된 executor가 포함된 기타 클라이언트 프로필을 사용해야 합니다. FAPI CIBA 사양의 요구 사항을 강제 적용하는 경우 기밀 클라이언트 또는 인증서 바인딩 액세스 토큰 적용과 같은 추가 요구 사항이 필요합니다.
2.5.2. OpenBanking CloudEventsil iPXE-grade API Security Profile
Red Hat Single Sign-On은 OpenBanking CloudEventsil CHAP-grade API Security Profile 1.0 Implementers DServiceVersion 2를 준수합니다. 이는 일부 요구 사항보다 FAPI 1 고급 사양보다 엄격한 요구사항이므로 일부 요구 사항을 적용하기 위해 클라이언트 정책을 보다 엄격하게 구성해야 할 수 있습니다. 특히 다음과 같습니다.
-
클라이언트가 PAR을 사용하지 않는 경우 암호화된 OIDC 요청 오브젝트를 사용하는지 확인합니다. 이를 위해 필요한
Encryption Required
로 구성된secure-request-object
executor가 있는 클라이언트 프로필을 사용할 수 있습니다. -
JWS의 경우 클라이언트는
PS256
알고리즘을 사용합니다. JWE의 경우 클라이언트는A256GCM
과 함께RSA-OAEP
를 사용해야 합니다. 이러한 알고리즘이 적용되는 모든 클라이언트 설정에서 이를 설정해야 할 수 있습니다.
2.5.3. TLS 고려 사항
기밀 정보가 교환되면 모든 상호 작용은 TLS(HTTPS)로 암호화됩니다. 또한 사용되는 암호화 제품군 및 TLS 프로토콜 버전에 대한 FAPI 사양에는 몇 가지 요구 사항이 있습니다. 이러한 요구 사항에 맞게 허용된 암호를 구성하는 것이 좋습니다. 이 구성은 Elytron 하위 시스템의 KEYCLOAK_HOME/standalone/configuration/standalone-*.xml
파일에서 수행할 수 있습니다. 예를 들어 이 요소는 tls
→ server-ssl-contexts
아래에 추가할 수 있습니다.
<server-ssl-context name="kcSSLContext" want-client-auth="true" protocols="TLSv1.2" \ key-manager="kcKeyManager" trust-manager="kcTrustManager" \ cipher-suite-filter="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" protocols="TLSv1.2" />
<server-ssl-context name="kcSSLContext" want-client-auth="true" protocols="TLSv1.2" \
key-manager="kcKeyManager" trust-manager="kcTrustManager" \
cipher-suite-filter="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" protocols="TLSv1.2" />
kcKeyManager
및 kcTrustManager
에 대한 참조는 해당 Keystore 및 Truststore를 참조합니다. 자세한 내용과 네트워크 설정 섹션 또는 X.509 인증 섹션 과 같은 Red Hat Single Sign-On 문서의 기타 부분은 Wildfly Elytron 하위 시스템 설명서를 참조하십시오.
3장. SAML을 사용하여 애플리케이션 및 서비스 보안
이 섹션에서는 Red Hat Single Sign-On 클라이언트 어댑터 또는 일반 SAML 공급자 라이브러리를 사용하여 SAML으로 애플리케이션 및 서비스를 보호하는 방법에 대해 설명합니다.
3.1. Java 어댑터
Red Hat Single Sign-On에는 다양한 Java 어댑터가 포함되어 있습니다. 올바른 어댑터를 선택하는 것은 대상 플랫폼에 따라 다릅니다.
3.1.1. 일반 어댑터 구성
Red Hat Single Sign-On에서 지원하는 각 SAML 클라이언트 어댑터는 간단한 XML 텍스트 파일을 통해 구성할 수 있습니다. 다음과 같이 표시됩니다.
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd"> <SP entityID="http://localhost:8081/sales-post-sig/" sslPolicy="EXTERNAL" nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" logoutPage="/logout.jsp" forceAuthentication="false" isPassive="false" turnOffChangeSessionIdOnLogin="false" autodetectBearerOnly="false"> <Keys> <Key signing="true" > <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/> <Certificate alias="http://localhost:8080/sales-post-sig/"/> </KeyStore> </Key> </Keys> <PrincipalNameMapping policy="FROM_NAME_ID"/> <RoleIdentifiers> <Attribute name="Role"/> </RoleIdentifiers> <RoleMappingsProvider id="properties-based-role-mapper"> <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/> </RoleMappingsProvider> <IDP entityID="idp" signaturesRequired="true"> <SingleSignOnService requestBinding="POST" bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" /> <SingleLogoutService requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" /> <Keys> <Key signing="true"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <Certificate alias="demo"/> </KeyStore> </Key> </Keys> </IDP> </SP> </keycloak-saml-adapter>
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd">
<SP entityID="http://localhost:8081/sales-post-sig/"
sslPolicy="EXTERNAL"
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
logoutPage="/logout.jsp"
forceAuthentication="false"
isPassive="false"
turnOffChangeSessionIdOnLogin="false"
autodetectBearerOnly="false">
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
<Certificate alias="http://localhost:8080/sales-post-sig/"/>
</KeyStore>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
<RoleIdentifiers>
<Attribute name="Role"/>
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP entityID="idp"
signaturesRequired="true">
<SingleSignOnService requestBinding="POST"
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
/>
<SingleLogoutService
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
/>
<Keys>
<Key signing="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
</SP>
</keycloak-saml-adapter>
이러한 설정 스위치 중 일부는 특정 어댑터일 수 있으며 일부는 모든 어댑터에서 일반적입니다. Java 어댑터의 경우 ${…}
엔클로저를 시스템 속성 교체로 사용할 수 있습니다. 예: ${jboss.server.config.dir}
.
3.1.1.1. SP 요소
다음은 SP 요소 특성에 대한 설명입니다.
<SP entityID="sp" sslPolicy="ssl" nameIDPolicyFormat="format" forceAuthentication="true" isPassive="false" keepDOMAssertion="true" autodetectBearerOnly="false"> ... </SP>
<SP entityID="sp"
sslPolicy="ssl"
nameIDPolicyFormat="format"
forceAuthentication="true"
isPassive="false"
keepDOMAssertion="true"
autodetectBearerOnly="false">
...
</SP>
- entityID
- 이 클라이언트의 식별자입니다. IdP는 클라이언트와 통신할 대상을 결정하기 위해 이 값이 필요합니다. 이 설정은 필수 항목입니다.
- sslPolicy
-
어댑터에서 적용할 SSL 정책입니다. 유효한 값은
모두
,EXTERNAL
,NONE
입니다. 모두에대해
모든 요청은 HTTPS를 통해 입력해야 합니다.EXTERNAL
의 경우, 비개인 IP 주소만 HTTPS를 통해 전선으로 전달되어야 합니다.NONE
의 경우 HTTPS를 통해 요청을 처리할 필요가 없습니다. 이 설정은 선택 사항입니다. 기본값은EXTERNAL
입니다. - nameIDPolicyFormat
-
SAML 클라이언트는 특정 NameID Subject 형식을 요청할 수 있습니다. 특정 형식을 원하는 경우 이 값을 입력합니다. 표준 SAML 형식 식별자(
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
)여야 합니다. 이 설정은 선택 사항입니다. 기본적으로 특수 형식이 요청되지 않습니다. - forceAuthentication
-
SAML 클라이언트는 이미 IdP에 로그인한 경우에도 사용자가 다시 인증되도록 요청할 수 있습니다. 활성화하려면
true
로 설정합니다. 이 설정은 선택 사항입니다. 기본값은false
입니다. - isPassive
-
SAML 클라이언트는 IdP에 로그인하지 않은 경우에도 사용자에게 인증을 요청하지 않도록 요청할 수 있습니다. 원한다면 이 값을
true
로 설정합니다.forceAuthentication
과 함께 사용하는 것은 반대이므로 사용하지 마십시오. 이 설정은 선택 사항입니다. 기본값은false
입니다. - turnOffChangeSessionIdOnLogin
-
일부 플랫폼에서 성공적인 로그인에 대해 세션 ID가 기본적으로 변경되어 보안 공격 벡터를 연결합니다. 이를 비활성화하려면 이를
true
로 변경하십시오. 이를 해제하지 않는 것이 좋습니다. 기본값은false
입니다. - autodetectBearerOnly
-
애플리케이션이 웹 애플리케이션 및 웹 서비스(예: CloudEvent 또는 REST)를 모두 제공하는 경우 true 로 설정해야 합니다. 이를 통해 인증되지 않은 웹 애플리케이션의 사용자를 Red Hat Single Sign-On 로그인 페이지로 리디렉션할 수 있지만 로그인 페이지로 리디렉션하지 않기 때문에 인증되지 않은 iPXE 또는 REST 클라이언트로 HTTP
401
상태 코드를 보낼 수 있습니다. Red Hat Single Sign-On은X-Requested-With
,ECDHEAction
또는Accept
와 같은 일반적인 헤더를 기반으로 합니다. 기본값은 false입니다. - logoutPage
-
이렇게 하면 로그아웃 후 표시할 페이지가 설정됩니다. 페이지가
http://web.example.com/logout.html
와 같은 전체 URL인 경우 HTTP302
상태 코드를 사용하여 해당 페이지로 로그아웃한 후 사용자가 리디렉션됩니다. 스키마 부분이 없는 링크(예:/logout.jsp
)가 지정된 경우 web.xml의보안
제한 선언에 따라 보호되는 영역에 있는지 여부와 관계없이 페이지가 배포 컨텍스트 루트와 관련하여 확인됩니다. - keepDOMAsertion
-
이 속성은 어댑터가 요청과 관련된 원래 형식의 어설션 표현을 저장하도록 설정되어야 합니다.
어설션 문서는 주체 내부의
getAssertionDocument
메서드를 사용하여 검색할 수 있습니다. 서명된 어설션을 다시 플레이할 때 특히 유용합니다. 반환된 문서는 Red Hat Single Sign-On 서버에서 수신한 SAML 응답을 구문 분석한 문서입니다. 이 설정은 OPTIONAL이고 기본값은 false 입니다(문서가 주체 내부에 저장되지 않음).
3.1.1.2. 서비스 공급자 키 및 키 요소
IdP에서 클라이언트 애플리케이션(또는 SP)이 모든 요청 및/또는 IdP에서 어설션을 암호화하도록 요구하는 경우, 이를 수행하는 데 사용되는 키를 정의해야 합니다. 클라이언트 서명 문서의 경우 문서에 서명하는 데 사용되는 개인 키 및 공개 키 또는 인증서를 모두 정의해야 합니다. 암호화의 경우 암호를 해독하는 데 사용되는 개인 키만 정의해야 합니다.
키를 설명하는 방법은 두 가지가 있습니다. Java KeyStore에 저장하거나 keycloak-saml.xml
내에 직접 키를 복사/붙여넣을 수 있습니다.
<Keys> <Key signing="true" > ... </Key> </Keys>
<Keys>
<Key signing="true" >
...
</Key>
</Keys>
Key
요소에는 서명
및 암호화
두 가지 선택적 속성이 있습니다. true로 설정하면 어댑터에 어떤 키가 사용될지 알려줍니다. 두 속성이 모두 true로 설정된 경우 키는 서명 문서에 모두 사용되며 암호화된 어설션의 암호를 해독하는 데 사용됩니다. 이러한 속성 중 하나 이상을 true로 설정해야 합니다.
3.1.1.2.1. KeyStore element
Key
요소 내에서 Java 키 저장소에서 키와 인증서를 로드할 수 있습니다. 이는 KeyStore
요소 내에 선언됩니다.
<Keys> <Key signing="true" > <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <PrivateKey alias="myPrivate" password="test123"/> <Certificate alias="myCertAlias"/> </KeyStore> </Key> </Keys>
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="myPrivate" password="test123"/>
<Certificate alias="myCertAlias"/>
</KeyStore>
</Key>
</Keys>
다음은 KeyStore
요소로 정의된 XML 구성 속성입니다.
- file
- 키 저장소의 파일 경로입니다. 이 옵션은 선택 사항입니다. file 또는 resource 속성을 설정해야 합니다.
- resource
- KeyStore의 WAR 리소스 경로입니다. 이는 메서드 호출에 사용되는 경로입니다. ServletContext.getResourceAsStream(). 이 옵션은 선택 사항입니다. file 또는 resource 속성을 설정해야 합니다.
- 암호
- KeyStore의 암호입니다. 이 옵션은 필수입니다.
SP가 문서에 서명하는 데 사용할 키를 정의하는 경우 Java KeyStore 내의 개인 키 및 인증서에 대한 참조도 지정해야 합니다. 위 예의 PrivateKey
및 Certificate
요소는 키 저장소 내의 키 또는 인증서를 가리키는 별칭
을 정의합니다. 키 저장소에 개인 키에 액세스하려면 추가 암호가 필요합니다. PrivateKey
요소에서 password
속성 내에서 이 암호를 정의해야 합니다.
3.1.1.2.2. 키 PEMS
Key
요소 내에서 PrivateKeyPem
,PublicKeyPem
및 CertificatePem
을 사용하여 키와 인증서를 직접 선언합니다. 이러한 요소에 포함된 값은 PEM 키 형식을 준수해야 합니다. openssl
또는 유사한 명령줄 도구를 사용하여 키를 생성하는 경우 일반적으로 이 옵션을 사용합니다.
<Keys> <Key signing="true"> <PrivateKeyPem> 2341251234AB31234==231BB998311222423522334 </PrivateKeyPem> <CertificatePem> 211111341251234AB31234==231BB998311222423522334 </CertificatePem> </Key> </Keys>
<Keys>
<Key signing="true">
<PrivateKeyPem>
2341251234AB31234==231BB998311222423522334
</PrivateKeyPem>
<CertificatePem>
211111341251234AB31234==231BB998311222423522334
</CertificatePem>
</Key>
</Keys>
3.1.1.3. SP PrincipalNameMapping 요소
이 요소는 선택 사항입니다. 10.0.0.1 ServletRequest.getUserPrincipal()와 같은 메서드에서 얻는 Java Principal
개체를 생성할 때 Principal.getName()
메서드에서 반환하는 이름을 정의할 수 있습니다.
<SP ...> <PrincipalNameMapping policy="FROM_NAME_ID"/> </SP> <SP ...> <PrincipalNameMapping policy="FROM_ATTRIBUTE" attribute="email" /> </SP>
<SP ...>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
</SP>
<SP ...>
<PrincipalNameMapping policy="FROM_ATTRIBUTE" attribute="email" />
</SP>
policy
속성은 이 값을 채우는 데 사용되는 정책을 정의합니다. 이 속성에 사용할 수 있는 값은 다음과 같습니다.
- FROM_NAME_ID
- 이 정책은 SAML 주체 값이 무엇이든 사용합니다. 기본 설정입니다.
- FROM_ATTRIBUTE
-
이렇게 하면 서버에서 수신한 SAML 어설션에 선언된 속성 중 하나에서 값을 가져옵니다. 특성 XML 특성 내에서 사용할 SAML 어설션 속성의 이름을 지정해야 합니다.
3.1.1.4. RoleIdentifiers 요소
RoleIdentifiers
요소는 사용자가 수신한 어설션 내에서 사용자의 자karta EE 보안 컨텍스트 내에서 역할 식별자로 사용해야 하는 SAML 속성을 정의합니다.
<RoleIdentifiers> <Attribute name="Role"/> <Attribute name="member"/> <Attribute name="memberOf"/> </RoleIdentifiers>
<RoleIdentifiers>
<Attribute name="Role"/>
<Attribute name="member"/>
<Attribute name="memberOf"/>
</RoleIdentifiers>
기본적으로 Role
특성 값은 Jakarta EE 역할로 변환됩니다. 일부 IdP는 member
또는 memberOf
특성 어설션을 사용하여 역할을 보냅니다. 하나 이상의 Attribute
요소를 정의하여 어떤 SAML 속성을 역할로 변환해야 하는지 지정할 수 있습니다.
3.1.1.5. RoleMappingsProvider 요소
RoleMappingsProvider
는 SAML 어댑터에서 사용할 수 있는 org.keycloak.adapters.saml.RoleMappingsProvider
SPI 구현의 ID 사양 및 구성을 허용하는 선택적 요소입니다.
Red Hat Single Sign-On을 IDP로 사용하는 경우 내장 역할 매퍼를 사용하여 SAML 어설션에 추가하기 전에 모든 역할을 매핑할 수 있습니다. 그러나 SAML 어댑터를 사용하여 SAML 요청을 타사 IDP에 보낼 수 있으며, 이 경우 어설션에서 추출된 역할을 SP에 필요한 다른 역할 집합에 매핑해야 할 수 있습니다. RoleMappingsProvider
SPI를 사용하면 필요한 매핑을 수행하는 데 사용할 수 있는 플러그형 역할 매퍼를 구성할 수 있습니다.
공급자 구성은 다음과 같습니다.
... <RoleIdentifiers> ... </RoleIdentifiers> <RoleMappingsProvider id="properties-based-role-mapper"> <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/> </RoleMappingsProvider> <IDP> ... </IDP>
...
<RoleIdentifiers>
...
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP>
...
</IDP>
id
속성은 설치된 공급자 중 사용할 공급자를 식별합니다. Property
하위 요소는 여러 번 사용하여 공급자의 구성 속성을 지정할 수 있습니다.
3.1.1.5.1. 속성 기반 역할 매핑 공급자
Red Hat Single Sign-On에는 속성
파일을 사용하여 역할 매핑을 수행하는 RoleMappingsProvider
구현이 포함되어 있습니다. 이 공급자는 id properties-based-role-mapper
로 식별되며 org.keycloak.adapters.saml.PropertiesBasedRoleMapper
클래스에 의해 구현됩니다.
이 공급자는 사용할 속성 파일의 위치를 지정하는 데 사용할 수 있는 두 가지 구성 속성을
사용합니다. 먼저 구성된 값을 사용하여 파일 시스템에서 속성 파일을 찾아 properties.file.location
속성이 지정되어 있는지 확인합니다. 구성된 파일이 없으면 공급자가
RuntimeException
을 생성합니다. 다음 스니펫에서는 properties.file.configuration
옵션을 사용하여 파일 시스템의 /opt/mappers/
디렉터리에서 roles.properties
파일을 로드하는 공급자의 예를 보여줍니다.
<RoleMappingsProvider id="properties-based-role-mapper"> <Property name="properties.file.location" value="/opt/mappers/roles.properties"/> </RoleMappingsProvider>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
</RoleMappingsProvider>
구성이 설정되지 않은 경우 공급자는 구성된 값을 사용하여 properties
.file.locationWAR
리소스에서 속성 파일을 로드하는 properties.resource.location
속성을 확인합니다. 이 구성 속성도 없으면 공급자는 기본적으로 / page -INF/role-mappings.properties
에서 파일을 로드하려고 합니다. 리소스에서 파일을 로드하지 않으면 공급자가 RuntimeException
이 발생합니다. 다음 스니펫에서는 properties.resource.location
을 사용하여 애플리케이션의 / page -INF/conf/
디렉터리에서 roles.properties
파일을 로드하는 공급자의 예를 보여줍니다.
<RoleMappingsProvider id="properties-based-role-mapper"> <Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/> </RoleMappingsProvider>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
</RoleMappingsProvider>
속성
파일은 역할과 보안 주체를 키로 포함할 수 있으며, 0개 이상의 역할 목록을 값으로 쉼표로 구분하여 포함할 수 있습니다. 메서드를 호출하면 매핑이 있는 경우 각 역할에 대해 어설션 및 검사에서 추출된 역할 집합을 반복합니다. 역할이 빈 역할에 매핑되면 해당 역할이 삭제됩니다. 하나 이상의 다른 역할 집합에 매핑되면 이러한 역할이 결과 세트에 설정됩니다. 역할에 대한 매핑을 찾을 수 없는 경우 결과 집합에 그대로 포함됩니다.
역할이 처리되면 구현에서 어설션에서 추출된 주체에 항목 속성 파일이 포함되어 있는지 확인합니다.Once the roles have been processed, the implementation checks if the principal extracted from the assertion contains an entry properties
file. 보안 주체에 대한 매핑이 있는 경우 값으로 나열된 모든 역할이 결과 세트에 추가됩니다. 이를 통해 주체에 추가 역할을 할당할 수 있습니다.
예를 들어 공급자가 다음 속성 파일을 사용하여 구성되었다고 가정하겠습니다.
roleA=roleX,roleY roleB= kc_user=roleZ
roleA=roleX,roleY
roleB=
kc_user=roleZ
primary kc_user
가 roleA
,roleB
및 roleC
가 있는 어설션에서 추출되면 roleA
가roleX
및 roleYY 둘 다에 매핑되므로 주체에 할당된 최종 역할 세트는 roleC
, roleX
,role
가 됩니다. Y
및 role
ZroleB
는 빈 역할에 매핑되어 삭제되고 roleC
가 그대로 사용되며 마지막으로 kc_user
주체(roleZ
)에 추가되어 있습니다.
참고: 매핑에 역할 이름에 공백을 사용하려면 공간에 유니코드 교체를 사용합니다. 예를 들어 들어오는 '역할 A'는 다음과 같습니다.
role\u0020A=roleX,roleY
role\u0020A=roleX,roleY
3.1.1.5.2. 자체 역할 매핑 공급자 추가
사용자 지정 역할 매핑 공급자를 추가하려면 org.keycloak.adapters.saml.RoleMappingsProvider
SPI를 구현해야 합니다. 자세한 내용은 서버 개발자 가이드 의 SAML 역할 매핑 SPI
섹션을 참조하십시오.
3.1.1.6. IDP 요소
IDP 요소의 모든 항목은 SP가 통신하는 ID 공급자(인증 서버)의 설정을 설명합니다.
<IDP entityID="idp" signaturesRequired="true" signatureAlgorithm="RSA_SHA1" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> ... </IDP>
<IDP entityID="idp"
signaturesRequired="true"
signatureAlgorithm="RSA_SHA1"
signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
...
</IDP>
다음은 IDP
요소 선언 내에서 지정할 수 있는 속성 구성 옵션입니다.
- entityID
- IDP의 발행자 ID입니다. 이 설정은 필수 항목입니다.
- signaturesRequired
-
true
로 설정하면 클라이언트 어댑터는 IDP로 전송하는 모든 문서에 서명합니다. 또한 클라이언트는 IDP가 전송된 문서에 서명할 것으로 예상합니다. 이 스위치는 모든 요청 및 응답 유형에 대한 기본값을 설정하지만 나중에 이에 대한 미세한 제어가 있음을 알 수 있습니다. 이 설정은 선택 사항이며 기본값은false
입니다. - signatureAlgorithm
-
IDP에서 서명된 문서가 사용할 것으로 예상되는 서명 알고리즘입니다. 허용되는 값은
RSA_SHA1
,RSA_SHA256
,RSA_SHA512
및DSA_SHA1
입니다. 이 설정은 OPTIONAL 이며 기본값은RSA_SHA256
입니다. - signatureCanonicalizationMethod
-
IDP에서 서명된 문서가 사용할 것으로 예상되는 서명 인증 방법입니다. 이 설정은 선택 사항입니다. 기본값은
http://www.w3.org/2001/10/xml-exc-c14n#
이며 대부분의 IDP에 적합해야 합니다. - metadataUrl
- IDP 메타데이터를 검색하는 데 사용되는 URL은 현재 이 키는 SP 측을 수동으로 변경하지 않고 IDP에서 이러한 키를 사이클링할 수 있도록 주기적으로 서명 및 암호화 키를 가져오는 데에만 사용됩니다.
3.1.1.7. IDP AllowedClockSkew 하위 요소
AllowedClockSkew
옵션 하위 요소는 IDP와 SP 사이에 허용되는 클럭 오차를 정의합니다. 기본값은 0입니다.
<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
- 단위
-
이 요소의 값에 연결된 시간 단위를 정의할 수 있습니다. 허용되는 값은MiCROSECONDS, MiLLISECONDS, MINUTES,ECDHENOSECONDS 및 IRQONDS입니다. 이것은 선택 사항입니다. 기본값은
SECONDS
입니다.
3.1.1.8. IDP SingleSignOnService 하위 요소
SingleSignOnService
하위 요소는 IDP의 로그인 SAML 엔드포인트를 정의합니다. 클라이언트 어댑터는 로그인할 때 이 요소 내의 설정을 통해 IDP 형식의 요청을 보냅니다.
<SingleSignOnService signRequest="true" validateResponseSignature="true" requestBinding="post" bindingUrl="url"/>
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="post"
bindingUrl="url"/>
다음은 이 요소에서 정의할 수 있는 구성 속성입니다.
- signRequest
-
클라이언트가 인증 요청에 서명해야 합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - validateResponseSignature
-
클라이언트는 IDP가 auhtn 요청에서 다시 전송된 어설션 응답 문서에 서명할 것으로 예상합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - requestBinding
-
IDP와 통신하는 데 사용되는 SAML 바인딩 유형입니다. 이 설정은 선택 사항입니다. 기본값은
POST
이지만REDIRECT
로 설정할 수도 있습니다. - responseBinding
-
SAML을 사용하면 클라이언트가 authn 응답에서 사용할 바인딩 유형을 요청할 수 있습니다. 이 값은
POST
또는REDIRECT
일 수 있습니다. 이 설정은 선택 사항입니다. 기본값은 클라이언트가 응답에 특정 바인딩 유형을 요청하지 않는다는 것입니다. - assertionConsumerServiceUrl
-
IDP 로그인 서비스가 응답을 보내야 하는 어설션 소비자 서비스(ACS)의 URL입니다. 이 설정은 선택 사항입니다. 기본적으로 IdP의 구성에 따라 설정되지 않습니다. 설정하는 경우
/saml
로 끝나야 합니다(예:http://sp.domain.com/my/endpoint/for/saml
). 이 속성의 값은 SAMLAuthnRequest
메시지의AssertionConsumerServiceURL
속성으로 전송됩니다. 이 속성에는 일반적으로responseBinding
속성이 함께 제공됩니다. - bindingUrl
- 클라이언트가 요청을 보낼 IDP 로그인 서비스의 URL입니다. 이 설정은 필수 항목입니다.
3.1.1.9. IDP SingleLogoutService 하위 요소
SingleLogoutService
하위 요소는 IDP의 로그 아웃 SAML 엔드포인트를 정의합니다. 클라이언트 어댑터는 로그아웃할 때 이 요소 내의 설정을 통해 IDP 형식의 요청을 보냅니다.
<SingleLogoutService validateRequestSignature="true" validateResponseSignature="true" signRequest="true" signResponse="true" requestBinding="redirect" responseBinding="post" postBindingUrl="posturl" redirectBindingUrl="redirecturl">
<SingleLogoutService validateRequestSignature="true"
validateResponseSignature="true"
signRequest="true"
signResponse="true"
requestBinding="redirect"
responseBinding="post"
postBindingUrl="posturl"
redirectBindingUrl="redirecturl">
- signRequest
-
클라이언트가 IDP에 요청하는 로그 아웃 요청에 서명해야 합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - signResponse
-
클라이언트가 IDP 요청에 전송하는 로그 아웃 응답에 서명해야 합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - validateRequestSignature
-
클라이언트가 IDP에서 서명한 로그 아웃 요청 문서를 예상해야합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - validateResponseSignature
-
클라이언트가 IDP에서 서명한 로그 아웃 응답 문서를 예상해야합니까? 이 설정은 선택 사항입니다. 기본값은 IDP
signaturesRequired
요소 값이 무엇이든입니다. - requestBinding
-
SAML 요청을 IDP에 전달하는 데 사용되는 SAML 바인딩 유형입니다. 이 설정은 선택 사항입니다. 기본값은
POST
이지만 REDIRECT로 설정할 수도 있습니다. - responseBinding
-
이는 SAML 응답을 IDP에 전달하는 데 사용되는 SAML 바인딩 유형입니다. 이 값은
POST
또는REDIRECT
일 수 있습니다. 이 설정은 선택 사항입니다. 기본값은POST
이지만REDIRECT
로 설정할 수도 있습니다. - postBindingUrl
-
POST 바인딩을 사용할 때 IDP의 logout 서비스의 URL입니다.
POST
바인딩을 사용하는 경우 이 설정은 REQUIRED 입니다. - redirectBindingUrl
- REDIRECT 바인딩을 사용할 때 IDP의 로그 아웃 서비스의 URL입니다. 이 설정은 REDIRECT 바인딩을 사용하는 경우 필수입니다.
3.1.1.10. IDP Keys 하위 요소
IDP의 Keys 하위 요소는 IDP에서 서명한 문서를 확인하는 데 사용할 인증서 또는 공개 키를 정의하는 데만 사용됩니다. SP의 Keys 요소 와 동일한 방식으로 정의됩니다. 하지만 다시는 하나의 인증서 또는 공개 키 참조만 정의해야 합니다. Red Hat Single Sign-On 서버 및 어댑터에서 IDP와 SP를 각각 실현하는 경우 서명 유효성 검사를 위한 키를 지정할 필요가 없습니다. 아래 내용을 참조하십시오.
SP와 IDP가 Red Hat Single Sign-On에 의해 구현되는 경우 게시된 인증서에서 IDP 서명 검증을 위해 자동으로 SP를 구성하도록 SP를 구성할 수 있습니다. 이는 Keys 하위 요소에서 서명 유효성 검사 키의 모든 선언을 제거하여 수행됩니다. Keys 하위 요소가 비어 있으면 완전히 생략할 수 있습니다. 그런 다음 이 키는 SAML 설명자에서 SP가 자동으로 가져옵니다.이 위치는 IDP SingleSignOnService 하위 요소에 지정된 SAML 엔드포인트 URL에서 파생됩니다. SAML 설명자 검색에 사용되는 HTTP 클라이언트의 설정에는 일반적으로 추가 구성이 필요하지 않지만 IDPECDHEClient 하위 요소에서 구성할 수 있습니다.
서명을 확인하기 위해 여러 키를 지정할 수도 있습니다. 이 작업은 signing
속성이 true
로 설정된 Keys 하위 요소에 여러 개의 Key 요소를 선언하여 수행됩니다. 이는 IDP 서명 키가 순환되는 경우의 경우 유용합니다. 일반적으로 새 SAML 프로토콜 메시지 및 어설션이 새 키로 서명되지만 이전 키로 서명된 키는 계속 수락되어야 합니다.
서명 확인 키를 자동으로 가져오고 추가 정적 서명 확인 키를 정의하도록 Red Hat Single Sign-On을 구성할 수 없습니다.
<IDP entityID="idp"> ... <Keys> <Key signing="true"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <Certificate alias="demo"/> </KeyStore> </Key> </Keys> </IDP>
<IDP entityID="idp">
...
<Keys>
<Key signing="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
3.1.1.11. IDPECDHEClient 하위 요소
10.0.0.1 Client
선택적 하위 요소는 사용 가능한 경우 IDP의 SAML 설명자를 통해 IDP 서명 확인을 위해 공개 키를 포함하는 인증서의 자동 취득에 사용되는 HTTP 클라이언트의 속성을 정의합니다.
<HttpClient connectionPoolSize="10" disableTrustManager="false" allowAnyHostname="false" clientKeystore="classpath:keystore.jks" clientKeystorePassword="pwd" truststore="classpath:truststore.jks" truststorePassword="pwd" proxyUrl="http://proxy/" socketTimeout="5000" connectionTimeout="6000" connectionTtl="500" />
<HttpClient connectionPoolSize="10"
disableTrustManager="false"
allowAnyHostname="false"
clientKeystore="classpath:keystore.jks"
clientKeystorePassword="pwd"
truststore="classpath:truststore.jks"
truststorePassword="pwd"
proxyUrl="http://proxy/"
socketTimeout="5000"
connectionTimeout="6000"
connectionTtl="500" />
- connectionPoolSize
-
이 구성 옵션은 풀링해야 하는 Red Hat Single Sign-On 서버에 대한 연결 수를 정의합니다. 이것은 선택 사항입니다. 기본값은
10
입니다. - disableTrustManager
-
Red Hat Single Sign-On 서버에 HTTPS가 필요하며 이 구성 옵션이
true
로 설정된 경우 truststore를 지정할 필요가 없습니다. 이 설정은 개발 중에만 사용해야 하며, SSL 인증서 확인을 비활성화하므로 프로덕션에서는 사용하지 않아야 합니다. 이것은 선택 사항입니다. 기본값은false
입니다. - allowAnyHostname
-
Red Hat Single Sign-On 서버에 HTTPS가 필요하며 이 구성 옵션이
true
로 설정되어 있으면 신뢰 저장소를 통해 Red Hat Single Sign-On 서버의 인증서의 유효성을 검사하지만 호스트 이름 검증은 수행되지 않습니다. 이 설정은 개발 중에만 사용해야 하며 프로덕션에서 는 SSL 인증서 확인을 부분적으로 비활성화하므로 사용하지 않아야 합니다. 이 설정은 테스트 환경에서 유용할 수 있습니다. 이것은 선택 사항입니다. 기본값은false
입니다. - truststore
-
값은 신뢰 저장소 파일의 파일 경로입니다. 경로 접두사를
classpath:
인 경우 대신 배포의 classpath에서 truststore를 가져옵니다. Red Hat Single Sign-On 서버로의 발신 HTTPS 통신에 사용됩니다. HTTPS 요청을 수행하는 클라이언트는 통신 중인 서버의 호스트를 확인할 방법이 필요합니다. 이것이 신뢰가 하는 것입니다. 키 저장소에는 하나 이상의 신뢰할 수 있는 호스트 인증서 또는 인증 기관이 포함됩니다. Red Hat Single Sign-On 서버의 SSL 키 저장소의 공개 인증서를 추출하여 이 신뢰 저장소를 생성할 수 있습니다.disableTrustManager
가true
인 경우를 제외하고 이 작업은 REQUIRED 입니다. - truststorePassword
-
신뢰 저장소의 암호입니다. truststore가 설정되어 있고
truststore
에 암호가 필요한 경우 REQUIRED 입니다. - clientKeystore
- 이는 키 저장소 파일의 파일 경로입니다. 이 키 저장소에 어댑터에서 Red Hat Single Sign-On 서버에 HTTPS 요청을 할 때 양방향 SSL에 대한 클라이언트 인증서가 포함되어 있습니다. 이것은 선택 사항입니다.
- clientKeystorePassword
-
클라이언트 키 저장소 및 클라이언트 키의 암호입니다.
clientKeystore
가 설정된 경우 REQUIRED 입니다. - proxyUrl
- HTTP 연결에 사용할 HTTP 프록시에 대한 URL입니다. 이것은 선택 사항입니다.
- socketTimeout
-
연결을 밀리초 단위로 설정한 후 데이터를 기다리는 소켓의 시간 초과입니다. 두 데이터 패킷 사이에 비활성의 최대 시간. 시간 제한 값이 0은 무한 타임아웃으로 해석됩니다. 음수 값은 정의되지 않은 것으로 해석됩니다(해당되는 경우 시스템 기본값). 기본값은
-1
입니다. 이것은 선택 사항입니다. - connectionTimeout
-
원격 호스트와의 연결을 밀리초 단위로 설정하기 위한 시간 초과입니다. 시간 제한 값이 0은 무한 타임아웃으로 해석됩니다. 음수 값은 정의되지 않은 것으로 해석됩니다(해당되는 경우 시스템 기본값). 기본값은
-1
입니다. 이것은 선택 사항입니다. - connectionTtl
-
클라이언트의 연결 시간(밀리초)입니다. 값이 0 보다 작거나 같은 값은 무한 값으로 해석됩니다.A value less than or equal to zero is interpreted as an infinite value. 기본값은
-1
입니다. 이것은 선택 사항입니다.
3.1.2. JBoss EAP 어댑터
JBoss EAP에 배포된 WAR 애플리케이션을 보호하려면 Red Hat Single Sign-On SAML 어댑터를 설치하고 구성해야 합니다.
그런 다음 WAR에 keycloak 구성 /ECDHE-INF/keycloak-saml.xml
파일을 제공하고 web.xml 내에서 auth-method를 KEYCLOAK-SAML으로 변경합니다.
ZIP 파일 또는 RPM을 사용하여 어댑터를 설치합니다.
3.1.3. ZIP 파일에서 어댑터 설치
각 어댑터는 Red Hat Single Sign-On 다운로드 사이트에서 별도의 다운로드입니다.
절차
다운로드 사이트에서 애플리케이션 서버에 적용되는 어댑터를 설치합니다.
JBoss EAP 7.x에 설치합니다.
cd $EAP_HOME unzip rh-sso-saml-eap7-adapter.zip
$ cd $EAP_HOME $ unzip rh-sso-saml-eap7-adapter.zip
Copy to Clipboard Copied! JBoss EAP 6.x에 설치합니다.
cd $EAP_HOME unzip rh-sso-saml-eap6-adapter.zip
$ cd $EAP_HOME $ unzip rh-sso-saml-eap6-adapter.zip
Copy to Clipboard Copied! 이러한 ZIP 파일은 JBoss EAP 배포 내에서 JBoss EAP SAML Adapter와 관련된 새로운 JBoss 모듈을 생성합니다.
CLI 스크립트를 사용하여 앱 서버의 서버 구성(
domain.xml
또는standalone.xml
) 내에서 Red Hat Single Sign-On SAML CloudEvent를 활성화합니다.서버를 시작하고 애플리케이션 서버에 적용되는 스크립트를 실행합니다.
JBoss EAP 7.1 이상에 이 명령 사용
cd $JBOSS_HOME ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
$ cd $JBOSS_HOME $ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
Copy to Clipboard Copied! 참고EAP는 7.4.CP7 및 7.4.CP8 이후 각각 OpenJDK 17 및 Oracle JDK 17을 지원합니다. 새로운 Java 버전은 elytron 변형을 필수이므로 JDK 17의 레거시 어댑터를 사용하지 마십시오. 또한 어댑터 CLI 파일을 실행한 후 EAP에서 제공하는
enable-elytron-se17.cli
스크립트를 실행합니다. elytron 어댑터를 구성하고 호환되지 않는 EAP 하위 시스템을 제거하려면 두 스크립트 모두 필요합니다. 자세한 내용은 이 보안 구성 변경 사항 문서를 참조하십시오.JBoss EAP 7.0 및 EAP 6.4에 대해 이 명령을 사용합니다.
cd $JBOSS_HOME ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cli
$ cd $JBOSS_HOME $ ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cli
Copy to Clipboard Copied! 참고JBoss EAP 7.1 이상에서 레거시 비Elytron 어댑터를 사용할 수 있습니다. 즉, 해당 버전에서도
어댑터-install-saml.cli
를 사용할 수 있습니다. 그러나 최신 Elytron 어댑터를 사용하는 것이 좋습니다.이 스크립트는 아래에 설명된 대로 확장 프로그램, 하위 시스템 및 선택적 security-domain을 추가합니다.
<server xmlns="urn:jboss:domain:1.4"> <extensions> <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/> ... </extensions> <profile> <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"/> ... </profile>
<server xmlns="urn:jboss:domain:1.4">
<extensions>
<extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
...
</extensions>
<profile>
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"/>
...
</profile>
호출 중인 NodePort(기타 EE 구성 요소)로 전파되도록 보안 웹 계층에서 생성된 보안 컨텍스트가 필요한 경우 keycloak
보안 도메인을 Egresss 및 기타 구성 요소와 함께 사용해야 합니다. 그렇지 않으면 이 구성은 선택 사항입니다.
<server xmlns="urn:jboss:domain:1.4"> <subsystem xmlns="urn:jboss:domain:security:1.2"> <security-domains> ... <security-domain name="keycloak"> <authentication> <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule" flag="required"/> </authentication> </security-domain> </security-domains>
<server xmlns="urn:jboss:domain:1.4">
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
...
<security-domain name="keycloak">
<authentication>
<login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule"
flag="required"/>
</authentication>
</security-domain>
</security-domains>
보안 컨텍스트는 Egress 계층으로 자동 전파됩니다.
3.1.3.1. JBoss SSO
JBoss EAP는 동일한 JBoss EAP 인스턴스에 배포된 웹 애플리케이션에 대한 SSO(Single Sign-On)를 기본적으로 지원합니다. Red Hat Single Sign-On을 사용할 때는 이 기능을 활성화해서는 안 됩니다.
3.1.3.2. JSESSIONID 쿠키의 SameSite 값 설정
브라우저는 Lax
에 대한 쿠키의 SameSite
특성에 대한 기본값을 설정할 계획입니다. 이 설정은 요청이 동일한 도메인에서 시작된 경우에만 쿠키가 애플리케이션에 전송됨을 의미합니다. 이 동작은 SAML POST 바인딩에 영향을 줄 수 있으며 작동하지 않을 수 있습니다. SAML 어댑터의 모든 기능을 유지하려면 컨테이너에서 생성한 JSESSIONID
쿠키에서 SameSite
값을 None
으로 설정하는 것이 좋습니다. 이렇게 하지 않으면 Red Hat Single Sign-On에 대한 각 요청으로 컨테이너의 세션이 재설정될 수 있습니다.
SameSite
특성을 None
으로 설정하지 않으려면 허용 가능한 경우 REDIRECT 바인딩 또는 이 해결 방법이 필요하지 않은 OIDC 프로토콜로 전환하는 것이 좋습니다.
Wildfly/EAP에서 JSESSIONID
쿠키의 SameSite
값을 None
으로 설정하려면 애플리케이션의 특정 콘텐츠와 함께 undertow
파일을 추가합니다.
-
handlers.conf
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
이 구성에 대한 지원은 Wildfly 버전 19.1.0에서 사용할 수 있습니다.
3.1.4. RPM에서 JBoss EAP 7 어댑터 설치
Red Hat Enterprise Linux 7에서는 채널이라는 용어가 리포지토리라는 이름으로 교체되었습니다. 이러한 명령에서는 리포지토리라는 용어만 사용됩니다.
사전 요구 사항
RPM에서 EAP 7 어댑터를 설치하려면 먼저 JBoss EAP 7 리포지토리를 구독해야 합니다.
- Red Hat Subscription Manager를 사용하여 Red Hat Enterprise Linux 시스템이 계정에 등록되어 있는지 확인하십시오. 자세한 내용은 Red Hat 서브스크립션 관리 설명서를 참조하십시오.
다른 JBoss EAP 리포지토리를 이미 구독한 경우 해당 리포지토리에서 먼저 구독 해제해야 합니다.
Red Hat Enterprise Linux 6, 7의 경우 7: Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 7.4 리포지토리를 구독하십시오. <RHEL_VERSION>을 Red Hat Enterprise Linux 버전에 따라 6 또는 7로 바꿉니다.
sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
Copy to Clipboard Copied! Red Hat Enterprise Linux 8의 경우: Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 7.4 리포지터리를 구독하십시오.
sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
$ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
Copy to Clipboard Copied!
절차
Red Hat Enterprise Linux 버전에 따라 SAML용 EAP 7 어댑터를 설치합니다.
Red Hat Linux 7에 설치합니다.
sudo yum install eap7-keycloak-saml-adapter-sso7_6
$ sudo yum install eap7-keycloak-saml-adapter-sso7_6
Copy to Clipboard Copied! Red Hat Enterprise Linux 8에 설치합니다.
sudo dnf install eap7-keycloak-adapter-sso7_6
$ sudo dnf install eap7-keycloak-adapter-sso7_6
Copy to Clipboard Copied! 참고RPM 설치의 기본 EAP_HOME 경로는 /opt/rh/eap7/root/usr/share/wildfly입니다.
SAML 모듈에 대한 설치 스크립트를 실행합니다.
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
Copy to Clipboard Copied!
설치가 완료되었습니다.
3.1.5. RPM에서 JBoss EAP 6 어댑터 설치
Red Hat Enterprise Linux 7에서는 채널이라는 용어가 리포지토리라는 이름으로 교체되었습니다. 이러한 명령에서는 리포지토리라는 용어만 사용됩니다.
사전 요구 사항
RPM에서 EAP 6 어댑터를 설치하려면 먼저 JBoss EAP 6 리포지토리를 구독해야 합니다.
- Red Hat Subscription Manager를 사용하여 Red Hat Enterprise Linux 시스템이 계정에 등록되어 있는지 확인하십시오. 자세한 내용은 Red Hat 서브스크립션 관리 설명서를 참조하십시오.
- 다른 JBoss EAP 리포지토리를 이미 구독한 경우 해당 리포지토리에서 먼저 구독 해제해야 합니다.
Red Hat Subscription Manager를 사용하여 다음 명령을 사용하여 JBoss EAP 6 리포지토리를 구독하십시오. <RHEL_VERSION>을 Red Hat Enterprise Linux 버전에 따라 6 또는 7로 바꿉니다.
sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
Copy to Clipboard Copied!
절차
다음 명령을 사용하여 SAML에 대한 EAP 6 어댑터를 설치합니다.
sudo yum install keycloak-saml-adapter-sso7_6-eap6
$ sudo yum install keycloak-saml-adapter-sso7_6-eap6
Copy to Clipboard Copied! 참고RPM 설치의 기본 EAP_HOME 경로는 /opt/rh/eap6/root/usr/share/wildfly입니다.
SAML 모듈에 대한 설치 스크립트를 실행합니다.
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
Copy to Clipboard Copied!
설치가 완료되었습니다.
3.1.5.1. WAR 보안
이 섹션에서는 WAR 패키지에 구성을 추가하고 파일을 편집하여 WAR를 직접 보호하는 방법을 설명합니다.
가장 먼저해야 할 작업은 WAR의 tries- INF
디렉터리에 keycloak-saml.xml
어댑터 구성 파일을 만드는 것입니다. 이 구성 파일의 형식은 일반 어댑터 구성 섹션에 설명되어 있습니다.
다음으로 web.xml
에서 auth-method
를 KEYCLOAK-SAML
으로 설정해야 합니다. 또한 표준 서블릿 보안을 사용하여 URL에 대한 역할 기반 제약 조건을 지정해야 합니다. 다음은 web.xml 파일의 예입니다.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <security-constraint> <web-resource-collection> <web-resource-name>Admins</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK-SAML</auth-method> <realm-name>this is ignored currently</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>customer-portal</module-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admins</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customers</web-resource-name>
<url-pattern>/customers/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK-SAML</auth-method>
<realm-name>this is ignored currently</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>
auth-method
설정을 제외한 모든 표준 서블릿 설정입니다.
3.1.5.2. Red Hat SSO(Single Sign-On SAML)를 사용하여 WAR 보안
Red Hat Single Sign-On으로 보안을 위해 WAR를 열 필요는 없습니다. 또는 Red Hat Single Sign-On SAML 어댑터를 통해 외부에서 보호할 수 있습니다. KEYCLOAK-SAML을 auth-method
로 지정할 필요는 없지만 web.xml
에서 security-constraints
를 정의해야 합니다. 그러나 WEB-INF/keycloak-saml.xml
파일을 만들 필요가 없습니다. 이 메타데이터는 대신 서버의 domain.xml
또는 standalone.xml
하위 시스템 구성 섹션의 XML 내에 정의됩니다.
<extensions> <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/> </extensions> <profile> <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"> <secure-deployment name="WAR MODULE NAME.war"> <SP entityID="APPLICATION URL"> ... </SP> </secure-deployment> </subsystem> </profile>
<extensions>
<extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
</extensions>
<profile>
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
<secure-deployment name="WAR MODULE NAME.war">
<SP entityID="APPLICATION URL">
...
</SP>
</secure-deployment>
</subsystem>
</profile>
secure-deployment
이름
속성은 보안하려는 WAR를 식별합니다. 해당 값은 .war
가 추가된 web.xml
에 정의된 module-name
입니다. 나머지 구성에서는 일반 어댑터 구성에 정의된 keycloak-saml.xml
구성과 동일한 XML 구문을 사용합니다.
예제 구성:
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"> <secure-deployment name="saml-post-encryption.war"> <SP entityID="http://localhost:8080/sales-post-enc/" sslPolicy="EXTERNAL" nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" logoutPage="/logout.jsp" forceAuthentication="false"> <Keys> <Key signing="true" encryption="true"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/> <Certificate alias="http://localhost:8080/sales-post-enc/"/> </KeyStore> </Key> </Keys> <PrincipalNameMapping policy="FROM_NAME_ID"/> <RoleIdentifiers> <Attribute name="Role"/> </RoleIdentifiers> <IDP entityID="idp"> <SingleSignOnService signRequest="true" validateResponseSignature="true" requestBinding="POST" bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/> <SingleLogoutService validateRequestSignature="true" validateResponseSignature="true" signRequest="true" signResponse="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml" redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/> <Keys> <Key signing="true" > <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <Certificate alias="saml-demo"/> </KeyStore> </Key> </Keys> </IDP> </SP> </secure-deployment> </subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
<secure-deployment name="saml-post-encryption.war">
<SP entityID="http://localhost:8080/sales-post-enc/"
sslPolicy="EXTERNAL"
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
logoutPage="/logout.jsp"
forceAuthentication="false">
<Keys>
<Key signing="true" encryption="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
<Certificate alias="http://localhost:8080/sales-post-enc/"/>
</KeyStore>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
<RoleIdentifiers>
<Attribute name="Role"/>
</RoleIdentifiers>
<IDP entityID="idp">
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="POST"
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
<SingleLogoutService
validateRequestSignature="true"
validateResponseSignature="true"
signRequest="true"
signResponse="true"
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="saml-demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
</SP>
</secure-deployment>
</subsystem>
3.1.6. Java Servlet 필터 어댑터
해당 서블릿 플랫폼에 대한 어댑터가 없는 Java 서블릿 애플리케이션과 함께 SAML을 사용하려면 Red Hat Single Sign-On이 보유한 서블릿 필터 어댑터를 사용할 수 있습니다. 이 어댑터는 다른 어댑터와 약간 다르게 작동합니다. 일반 어댑터 구성 섹션에 정의된 대로 /anchor-INF/keycloak-saml.xml
파일을 지정해야 하지만 web.xml 에서 보안 제약 조건을 정의하지는 않습니다. 대신 Red Hat Single Sign-On 서블릿 필터 어댑터를 사용하여 필터 매핑을 정의하여 보안하려는 URL 패턴을 보호합니다.
Backchannel logout은 표준 어댑터와 약간 다르게 작동합니다. http 세션을 무효화하지 않고 세션 ID를 로그아웃한 것으로 표시합니다. 세션 ID를 기반으로 http 세션을 임의로 무효화할 수 있는 방법은 없습니다.
SAML 필터를 사용하는 클러스터된 애플리케이션이 있는 경우 현재 Backchannel 로그 아웃이 작동하지 않습니다.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <filter> <filter-name>Keycloak Filter</filter-name> <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class> </filter> <filter-mapping> <filter-name>Keycloak Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>customer-portal</module-name>
<filter>
<filter-name>Keycloak Filter</filter-name>
<filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Keycloak Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Red Hat Single Sign-On 필터에는 다른 어댑터와 동일한 구성 매개 변수가 있습니다. 컨텍스트 매개변수 대신 filter init params로 정의해야 합니다.
보안 및 안전하지 않은 URL 패턴이 다양한 경우 여러 필터 매핑을 정의할 수 있습니다.
/saml
를 포함하는 필터 매핑이 있어야 합니다. 이 매핑은 모든 서버 콜백을 다룹니다.
IdP로 SP를 등록할 때 http[s]://hostname/{context-root}/saml
를 Assert Consumer 서비스 URL 및 Single Logout 서비스 URL로 등록해야 합니다.
이 필터를 사용하려면 다음 maven 아티팩트를 WAR poms에 포함합니다.
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-saml-servlet-filter-adapter</artifactId> <version>18.0.18.redhat-00001</version> </dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
<version>18.0.18.redhat-00001</version>
</dependency>
Multi Tenancy 를 사용하려면 keycloak.config.resolver
매개변수를 필터 매개변수로 전달해야 합니다.
<filter> <filter-name>Keycloak Filter</filter-name> <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class> <init-param> <param-name>keycloak.config.resolver</param-name> <param-value>example.SamlMultiTenantResolver</param-value> </init-param> </filter>
<filter>
<filter-name>Keycloak Filter</filter-name>
<filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
<init-param>
<param-name>keycloak.config.resolver</param-name>
<param-value>example.SamlMultiTenantResolver</param-value>
</init-param>
</filter>
3.1.7. ID 공급자에 등록
각 서블릿 기반 어댑터의 경우, 어설션 소비자 서비스 URL 및 단일 로그 아웃 서비스에 등록한 끝점은 /saml
가 추가된 서블릿 애플리케이션의 기본 URL이어야 합니다(즉, https://example.com/contextPath/saml
).
3.1.8. logout
웹 애플리케이션에서 로그아웃하는 방법은 여러 가지가 있습니다. Jakarta EE 서블릿 컨테이너의 경우>-< ServletRequest.logout()
을 호출할 수 있습니다. 다른 브라우저 애플리케이션의 경우 보안 제한 조건이 있고 쿼리 매개변수 GLO(예: http://myapp?GLO=true
)를 전달하는 웹 애플리케이션의 URL을 지정할 수 있습니다. 브라우저에서 SSO 세션이 있는 경우 로그아웃됩니다.
3.1.8.1. 클러스터된 환경에서 로그아웃
내부적으로 SAML 어댑터는 SAML 세션 인덱스, 주체 이름(알려진 경우) 및 HTTP 세션 ID 간의 매핑을 저장합니다. 이 매핑은 배포 가능한 애플리케이션을 위해 클러스터 전체의 JBoss 애플리케이션 서버 제품군(10/11, EAP 6/7)에서 유지 관리할 수 있습니다. 사전 조건으로서 HTTP 세션을 클러스터에 배포해야 합니다(즉, 애플리케이션은 애플리케이션의 web.xml
에서 < distributable/
> 태그로 표시됩니다).
기능을 활성화하려면 /proj _INF/web.xml 파일에 다음 섹션을 추가합니다.
EAP 7의 경우 WildFly 10/11:
<context-param> <param-name>keycloak.sessionIdMapperUpdater.classes</param-name> <param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value> </context-param>
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
EAP 6의 경우:
<context-param> <param-name>keycloak.sessionIdMapperUpdater.classes</param-name> <param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value> </context-param>
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
배포의 세션 캐시 이름이 deployment-cache
인 경우 SAML 매핑에 사용되는 캐시의 이름은 deployment-cache.ssoCache
로 지정됩니다. 캐시 이름은 컨텍스트 매개변수 keycloak.sessionIdMapperUpdater.infinispan.cacheName
으로 덮어쓸 수 있습니다. 캐시가 포함된 캐시 컨테이너는 배포 세션 캐시를 포함하는 것과 동일하지만 컨텍스트 매개변수 keycloak.sessionIdMapperUpdater.infinispan.containerName
으로 덮어쓸 수 있습니다.
기본적으로 SAML 매핑 캐시 구성은 세션 캐시에서 파생됩니다. 이 구성은 다른 캐시와 마찬가지로 서버의 캐시 구성 섹션에서 수동으로 재정의할 수 있습니다.
현재는 SAML 세션 캐시에 복제된 캐시를 사용하는 것이 좋습니다. 분산 캐시를 사용하면 SAML 로그 아웃 요청이 SAML 세션 인덱스에 액세스할 수 없는 HTTP 세션 매핑에 액세스할 수 없는 결과가 발생하여 로그 아웃에 실패할 수 있습니다.
3.1.8.2. 사이트 간 시나리오에서 로그아웃
교차 사이트 시나리오는 WildFly 10 이상 및 EAP 7 이상에만 적용됩니다.
여러 데이터 센터에 걸쳐 있는 세션을 처리하기 위해서는 특별한 처리가 필요합니다. 다음 시나리오를 고려해 보십시오.
- 로그인 요청은 데이터 센터 1의 클러스터 내에서 처리됩니다.
- admin은 특정 SAML 세션에 대한 로그아웃 요청을 발행하고 요청은 데이터 센터 2에 있습니다.
데이터 센터 2는 데이터 센터 1(및 HTTP 세션을 공유하는 다른 모든 데이터 센터)에 있는 모든 세션을 로그아웃해야 합니다.
이 경우 위에서 설명한 SAML 세션 캐시는 개별 클러스터뿐만 아니라 예를 들어 독립 실행형 Infinispan/JDG 서버를 통해 모든 데이터 센터에 복제해야 합니다.
- 독립 실행형 Infinispan/JDG 서버에 캐시를 추가해야 합니다.
- 이전 항목의 캐시는 각 SAML 세션 캐시에 대한 원격 저장소로 추가해야 합니다.
배포 중에 원격 저장소가 SAML 세션 캐시에 있는 것으로 확인되면 변경 사항을 감시하고 로컬 SAML 세션 캐시가 적절하게 업데이트됩니다.
3.1.9. 어설션 특성 가져오기
SAML 로그인에 성공한 후 애플리케이션 코드에서 SAML 어설션과 함께 전달된 특성 값을 가져올 수 있습니다. iPXE ServletRequest.getUserPrincipal()
는 org.keycloak.adapters.saml.Saml
라는 Red Hat Single Sign-On 특정 클래스에 Podcast를 입력할 수 있는 Principal 오브젝트를 반환합니다. 이 오브젝트를 사용하면 원시 어설션을 볼 수 있으며 속성 값을 조회하는 편의성 함수도 있습니다.
Principal
package org.keycloak.adapters.saml; public class SamlPrincipal implements Serializable, Principal { /** * Get full saml assertion * * @return */ public AssertionType getAssertion() { ... } /** * Get SAML subject sent in assertion * * @return */ public String getSamlSubject() { ... } /** * Subject nameID format * * @return */ public String getNameIDFormat() { ... } @Override public String getName() { ... } /** * Convenience function that gets Attribute value by attribute name * * @param name * @return */ public List<String> getAttributes(String name) { ... } /** * Convenience function that gets Attribute value by attribute friendly name * * @param friendlyName * @return */ public List<String> getFriendlyAttributes(String friendlyName) { ... } /** * Convenience function that gets first value of an attribute by attribute name * * @param name * @return */ public String getAttribute(String name) { ... } /** * Convenience function that gets first value of an attribute by attribute name * * * @param friendlyName * @return */ public String getFriendlyAttribute(String friendlyName) { ... } /** * Get set of all assertion attribute names * * @return */ public Set<String> getAttributeNames() { ... } /** * Get set of all assertion friendly attribute names * * @return */ public Set<String> getFriendlyNames() { ... } }
package org.keycloak.adapters.saml;
public class SamlPrincipal implements Serializable, Principal {
/**
* Get full saml assertion
*
* @return
*/
public AssertionType getAssertion() {
...
}
/**
* Get SAML subject sent in assertion
*
* @return
*/
public String getSamlSubject() {
...
}
/**
* Subject nameID format
*
* @return
*/
public String getNameIDFormat() {
...
}
@Override
public String getName() {
...
}
/**
* Convenience function that gets Attribute value by attribute name
*
* @param name
* @return
*/
public List<String> getAttributes(String name) {
...
}
/**
* Convenience function that gets Attribute value by attribute friendly name
*
* @param friendlyName
* @return
*/
public List<String> getFriendlyAttributes(String friendlyName) {
...
}
/**
* Convenience function that gets first value of an attribute by attribute name
*
* @param name
* @return
*/
public String getAttribute(String name) {
...
}
/**
* Convenience function that gets first value of an attribute by attribute name
*
*
* @param friendlyName
* @return
*/
public String getFriendlyAttribute(String friendlyName) {
...
}
/**
* Get set of all assertion attribute names
*
* @return
*/
public Set<String> getAttributeNames() {
...
}
/**
* Get set of all assertion friendly attribute names
*
* @return
*/
public Set<String> getFriendlyNames() {
...
}
}
3.1.10. 오류 처리
Red Hat Single Sign-On에는 서블릿 기반 클라이언트 어댑터의 일부 오류 처리 기능이 있습니다. 인증 시 오류가 발생하면 클라이언트 어댑터는>-< ServletResponse.sendError()
를 호출합니다. web.xml
파일 내에 오류 페이지를
설정하여 원하는 오류를 처리할 수 있습니다. 클라이언트 어댑터는 400, 401, 403 및 500 오류가 발생할 수 있습니다.
<error-page> <error-code>403</error-code> <location>/ErrorHandler</location> </error-page>
<error-page>
<error-code>403</error-code>
<location>/ErrorHandler</location>
</error-page>
클라이언트 어댑터는 검색할 수 있는 10.0.0.1ServletRequest
속성도 설정합니다. 특성 이름은 org.keycloak.adapters.spi.AuthenticationError
입니다. 이 오브젝트를 org.keycloak.adapters.saml.SamlAuthenticationError
로 생성합니다. 이 클래스는 어떤 일이 발생했는지 정확히 알려줍니다. 이 속성을 설정하지 않으면 어댑터에서 오류 코드에 대한 책임이 없었습니다.
public class SamlAuthenticationError implements AuthenticationError { public static enum Reason { EXTRACTION_FAILURE, INVALID_SIGNATURE, ERROR_STATUS } public Reason getReason() { return reason; } public StatusResponseType getStatus() { return status; } }
public class SamlAuthenticationError implements AuthenticationError {
public static enum Reason {
EXTRACTION_FAILURE,
INVALID_SIGNATURE,
ERROR_STATUS
}
public Reason getReason() {
return reason;
}
public StatusResponseType getStatus() {
return status;
}
}
3.1.11. 문제 해결
문제를 해결하는 가장 좋은 방법은 클라이언트 어댑터와 Red Hat Single Sign-On Server 모두에서 SAML 디버깅을 켜는 것입니다. 로깅 프레임워크를 사용하여 org.keycloak.saml
패키지의 로그 수준을 DEBUG
로 설정합니다. 이 기능을 켜면 SAML 요청 및 응답 문서가 서버로 전송되고 있음을 확인할 수 있습니다.
3.1.12. 멀티 테넌시
SAML은 OIDC for Multi Tenancy 와 동일한 기능을 제공합니다. 즉, 여러 Red Hat Single Sign-On 영역으로 단일 대상 애플리케이션(WAR)을 보호할 수 있습니다. 이 영역은 동일한 Red Hat Single Sign-On 인스턴스 또는 다른 인스턴스에 있을 수 있습니다.
이렇게 하려면 애플리케이션에 여러 keycloak-saml.xml
어댑터 구성 파일이 있어야 합니다.
다른 컨텍스트 경로에 배포된 다른 어댑터 구성 파일이 있는 WAR의 여러 인스턴스가 있을 수 있지만 불편할 수 있으며 context-path 이외의 다른 항목을 기반으로 영역을 선택할 수도 있습니다.
Red Hat Single Sign-On을 사용하면 사용자 정의 구성 해결 프로그램을 사용할 수 있으므로 각 요청에 사용되는 어댑터 구성을 선택할 수 있습니다. SAML에서 구성은 로그인 처리에만 관심이 있습니다. 사용자가 로그인하면 세션이 인증되고 반환된 keycloak-saml.xml
이 다른지 중요하지 않습니다. 따라서 동일한 세션에 대해 동일한 구성을 반환하는 것이 올바른 방법입니다.
이를 위해 org.keycloak.adapters.saml.SamlConfigResolver
구현을 생성합니다. 다음 예제에서는 Host
헤더를 사용하여 적절한 구성을 찾아서 애플리케이션과 관련된 요소를 애플리케이션의 Java 클래스 경로에서 로드합니다.
package example; import java.io.InputStream; import org.keycloak.adapters.saml.SamlConfigResolver; import org.keycloak.adapters.saml.SamlDeployment; import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder; import org.keycloak.adapters.saml.config.parsers.ResourceLoader; import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.saml.common.exceptions.ParsingException; public class SamlMultiTenantResolver implements SamlConfigResolver { @Override public SamlDeployment resolve(HttpFacade.Request request) { String host = request.getHeader("Host"); String realm = null; if (host.contains("tenant1")) { realm = "tenant1"; } else if (host.contains("tenant2")) { realm = "tenant2"; } else { throw new IllegalStateException("Not able to guess the keycloak-saml.xml to load"); } InputStream is = getClass().getResourceAsStream("/" + realm + "-keycloak-saml.xml"); if (is == null) { throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak-saml.xml"); } ResourceLoader loader = new ResourceLoader() { @Override public InputStream getResourceAsStream(String path) { return getClass().getResourceAsStream(path); } }; try { return new DeploymentBuilder().build(is, loader); } catch (ParsingException e) { throw new IllegalStateException("Cannot load SAML deployment", e); } } }
package example;
import java.io.InputStream;
import org.keycloak.adapters.saml.SamlConfigResolver;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.saml.common.exceptions.ParsingException;
public class SamlMultiTenantResolver implements SamlConfigResolver {
@Override
public SamlDeployment resolve(HttpFacade.Request request) {
String host = request.getHeader("Host");
String realm = null;
if (host.contains("tenant1")) {
realm = "tenant1";
} else if (host.contains("tenant2")) {
realm = "tenant2";
} else {
throw new IllegalStateException("Not able to guess the keycloak-saml.xml to load");
}
InputStream is = getClass().getResourceAsStream("/" + realm + "-keycloak-saml.xml");
if (is == null) {
throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak-saml.xml");
}
ResourceLoader loader = new ResourceLoader() {
@Override
public InputStream getResourceAsStream(String path) {
return getClass().getResourceAsStream(path);
}
};
try {
return new DeploymentBuilder().build(is, loader);
} catch (ParsingException e) {
throw new IllegalStateException("Cannot load SAML deployment", e);
}
}
}
web.xml
의 keycloak.config.resolver
context-param과 함께 사용할 SamlConfigResolver
구현도 구성해야 합니다.
<web-app> ... <context-param> <param-name>keycloak.config.resolver</param-name> <param-value>example.SamlMultiTenantResolver</param-value> </context-param> </web-app>
<web-app>
...
<context-param>
<param-name>keycloak.config.resolver</param-name>
<param-value>example.SamlMultiTenantResolver</param-value>
</context-param>
</web-app>
3.2. mod_auth_mellon Apache HTTPD 모듈
mod_auth_mellon 모듈은 SAML용 Apache HTTPD 플러그인입니다. 언어/환경에서 Apache HTTPD 사용을 프록시로 지원하는 경우 mod_auth_mellon을 사용하여 SAML으로 웹 애플리케이션을 보호할 수 있습니다. 이 모듈에 대한 자세한 내용은 mod_auth_mellon GitHub 리포지터리를 참조하십시오.
mod_auth_mellon을 구성하려면 다음이 필요합니다.
- Red Hat Single Sign-On 또는 다른 SAML IdP에 대한 연결을 설명하는 IdM(Identity Provider) 엔티티 설명자 XML 파일
- 보안 중인 애플리케이션에 대한 SAML 연결 및 구성을 설명하는 SP 엔티티 설명자 XML 파일입니다.
- 애플리케이션이 문서에 서명하는 데 사용하는 개인 키를 정의하는 PEM 형식의 텍스트 파일인 개인 키 PEM 파일입니다.
- 애플리케이션의 인증서를 정의하는 텍스트 파일인 인증서 PEM 파일입니다.
- mod_auth_mellon 특정 Apache HTTPD 모듈 구성.
3.2.1. Red Hat Single Sign-On을 사용하여 mod_auth_mellon 구성
두 개의 호스트가 관련되어 있습니다.
- Red Hat Single Sign-On이 실행 중인 호스트는 Red Hat Single Sign-On이 SAML ID 공급자(IdP)이기 때문에 $idp_host라고 합니다.
- 웹 애플리케이션이 실행 중인 호스트는 $sp_host라고 합니다. SAML에서 IdP를 사용하는 애플리케이션을 서비스 공급자(SP)라고 합니다.
다음 단계는 모두 root 권한이 있는 $sp_host에서 수행해야 합니다.
3.2.1.1. 패키지 설치
필요한 패키지를 설치하려면 다음이 필요합니다.
- Apache Web Server (httpd)
- Apache용 Mellon SAML SP 애드온 모듈
- X509 인증서를 생성하는 툴
필요한 패키지를 설치하려면 다음 명령을 실행합니다.
yum install httpd mod_auth_mellon mod_ssl openssl
yum install httpd mod_auth_mellon mod_ssl openssl
3.2.1.2. Apache SAML용 구성 디렉터리 생성
Apache의 SAML 사용과 관련된 구성 파일을 한 위치에 유지하는 것이 좋습니다.
Apache 구성 루트 /etc/httpd에 있는 saml2라는 새 디렉터리를 만듭니다.
mkdir /etc/httpd/saml2
mkdir /etc/httpd/saml2
3.2.1.3. Mellon 서비스 공급자 구성
Apache 애드온 모듈의 구성 파일은 /etc/httpd/conf.d 디렉터리에 있으며 파일 이름 확장자는 .conf입니다. /etc/httpd/conf.d/mellon.conf 파일을 만들고 여기에 Mellon의 설정 지시문을 배치해야 합니다.
Mellon의 설정 지시문은 대략 두 가지 정보 클래스로 나눌 수 있습니다.
- SAML 인증으로 보호할 URL
- 보호된 URL이 참조될 때 사용되는 SAML 매개변수는 무엇입니까.
Apache 구성 지시문은 일반적으로 위치라고 하는 URL 공간의 계층적 트리 구조를 따릅니다. 보호하려면 Mellon에 대해 하나 이상의 URL 위치를 지정해야 합니다. 각 위치에 적용되는 구성 매개 변수를 추가하는 방법에 유연성이 있습니다. 필요한 모든 매개 변수를 location 블록에 추가하거나 URL 위치 계층 구조(또는 두 위치의 일부 조합)에서 높은 공통 위치에 Mellon 매개변수를 추가할 수 있습니다. SP가 어떤 위치에 SAML 작업을 트리거하는지와 관계없이 동일한 방식으로 작동하는 것이 일반적이므로 여기에 사용되는 예제 구성은 계층 구조의 루트에 공통 Mellon 구성 지시문을 배치하고 Mellon에 의해 보호될 특정 위치를 최소 지시문으로 정의할 수 있습니다. 이 전략은 보호되는 각 위치에 대해 동일한 매개변수를 중복하지 않도록 합니다.
이 예제에는 하나의 보호 위치(https://$sp_host/private)만 있습니다.
Mellon 서비스 공급자를 구성하려면 다음 절차를 수행합니다.
절차
- 다음 내용으로 /etc/httpd/conf.d/mellon.conf 파일을 만듭니다.
<Location / > MellonEnable info MellonEndpointPath /mellon/ MellonSPMetadataFile /etc/httpd/saml2/mellon_metadata.xml MellonSPPrivateKeyFile /etc/httpd/saml2/mellon.key MellonSPCertFile /etc/httpd/saml2/mellon.crt MellonIdPMetadataFile /etc/httpd/saml2/idp_metadata.xml </Location> <Location /private > AuthType Mellon MellonEnable auth Require valid-user </Location>
<Location / >
MellonEnable info
MellonEndpointPath /mellon/
MellonSPMetadataFile /etc/httpd/saml2/mellon_metadata.xml
MellonSPPrivateKeyFile /etc/httpd/saml2/mellon.key
MellonSPCertFile /etc/httpd/saml2/mellon.crt
MellonIdPMetadataFile /etc/httpd/saml2/idp_metadata.xml
</Location>
<Location /private >
AuthType Mellon
MellonEnable auth
Require valid-user
</Location>
위 코드에서 참조하는 일부 파일은 이후 단계에서 생성됩니다.
3.2.2. mod_auth_mellon에서 사용하는 쿠키의 SameSite 값 설정
브라우저는 Lax
에 대한 쿠키의 SameSite
특성에 대한 기본값을 설정할 계획입니다. 이 설정은 요청이 동일한 도메인에서 시작된 경우에만 쿠키가 애플리케이션에 전송됨을 의미합니다. 이 동작은 SAML POST 바인딩에 영향을 줄 수 있으며 작동하지 않을 수 있습니다. mod_auth_mellon 모듈의 전체 기능을 유지하려면 mod_auth_mellon 에서 생성한 쿠키의 SameSite
값을 None
으로 설정하는 것이 좋습니다. 그러지 않으면 Red Hat Single Sign-On을 사용하여 로그인할 수 없게 될 수 있습니다.
SameSite
값을 None
으로 설정하려면 다음 구성을 mellon.conf
파일 내의 < Location /
> tag에 추가합니다.
MellonSecureCookie On MellonCookieSameSite none
MellonSecureCookie On
MellonCookieSameSite none
이 구성에 대한 지원은 버전 0.16.0의 mod_auth_mellon 모듈에서 사용할 수 있습니다.
3.2.2.1. 서비스 공급자 메타데이터 생성
SAML IdP 및 SP에서 SAML 메타데이터는 XML 형식으로 되어 있습니다. 메타데이터의 스키마는 표준이므로 참여 SAML 엔티티는 서로의 메타데이터를 사용할 수 있습니다. 다음이 필요합니다.
- SP가 사용하는 IdP의 메타데이터
- IdP에 제공된 SP에 대한 메타데이터
SAML 메타데이터의 구성 요소 중 하나는 X509 인증서입니다. 이러한 인증서는 다음 두 가지 용도로 사용됩니다.
- 수신 엔드가 예상 당사자로부터 시작된 메시지를 입증할 수 있도록 SAML 메시지에 서명합니다.
- 전송 중에 메시지 암호화 (일반적으로 TLS 보호 전송에서 SAML 메시지가 발생하기 때문에 거의 사용되지 않음)
이미 CA(인증 기관)가 있거나 자체 서명된 인증서를 생성할 수 있는 경우 자체 인증서를 사용할 수 있습니다. 이 예에서는 단순화를 위해 자체 서명된 인증서가 사용됩니다.
Mellon의 SP 메타데이터는 mod_auth_mellon 버전의 기능을 반영해야 하며, 유효한 SP 메타데이터 XML이어야 하며 X509 인증서(X509 인증서 생성에 익숙해지지 않는 경우)를 포함해야 하며, SP 메타데이터를 생성하는 가장 빠른 방법은 mod_auth_mellon 패키지에 포함된 도구를 사용하는 것입니다. 생성된 메타데이터는 텍스트 파일이므로 항상 나중에 편집할 수 있습니다. 또한 X509 키와 인증서를 생성합니다.
SAML IdP 및 SP는 EntityID로 알려진 고유한 이름을 사용하여 자신을 식별합니다. Mellon 메타데이터 생성 툴을 사용하려면 다음이 필요합니다.
- 일반적으로 SP의 URL이며 종종 SP 메타데이터를 검색할 수 있는 SP의 URL입니다.
- SP에 대한 SAML 메시지가 사용되는 URL로, Mellon이 MellonEndanchorPath를 호출합니다.
SP 메타데이터를 생성하려면 다음 절차를 수행합니다.
절차
몇 가지 도우미 쉘 변수를 생성합니다.
fqdn=`hostname` mellon_endpoint_url="https://${fqdn}/mellon" mellon_entity_id="${mellon_endpoint_url}/metadata" file_prefix="$(echo "$mellon_entity_id" | sed 's/[^A-Za-z.]/_/g' | sed 's/__*/_/g')"
fqdn=`hostname` mellon_endpoint_url="https://${fqdn}/mellon" mellon_entity_id="${mellon_endpoint_url}/metadata" file_prefix="$(echo "$mellon_entity_id" | sed 's/[^A-Za-z.]/_/g' | sed 's/__*/_/g')"
Copy to Clipboard Copied! 다음 명령을 실행하여 Mellon 메타데이터 생성 툴을 호출합니다.
/usr/libexec/mod_auth_mellon/mellon_create_metadata.sh $mellon_entity_id $mellon_endpoint_url
/usr/libexec/mod_auth_mellon/mellon_create_metadata.sh $mellon_entity_id $mellon_endpoint_url
Copy to Clipboard Copied! 생성된 파일을 해당 대상으로 이동합니다(위에 생성된 /etc/httpd/conf.d/mellon.conf 파일에서 참조됨).
mv ${file_prefix}.cert /etc/httpd/saml2/mellon.crt mv ${file_prefix}.key /etc/httpd/saml2/mellon.key mv ${file_prefix}.xml /etc/httpd/saml2/mellon_metadata.xml
mv ${file_prefix}.cert /etc/httpd/saml2/mellon.crt mv ${file_prefix}.key /etc/httpd/saml2/mellon.key mv ${file_prefix}.xml /etc/httpd/saml2/mellon_metadata.xml
Copy to Clipboard Copied!
3.2.2.2. Red Hat Single Sign-On ID 공급자에 Mellon 서비스 공급자 추가
가정: Red Hat Single Sign-On IdP가 $idp_host에 이미 설치되어 있습니다.
Red Hat Single Sign-On은 모든 사용자, 클라이언트 등을 영역으로 그룹화하는 여러 테넌시를 지원합니다. 각 영역은 다른 영역과 독립적입니다. Red Hat Single Sign-On에서 기존 영역을 사용할 수 있지만 이 예제에서는 test_realm이라는 새 영역을 생성하고 해당 영역을 사용하는 방법을 보여줍니다.
이러한 모든 작업은 Red Hat Single Sign-On 관리 콘솔을 사용하여 수행됩니다. 다음 절차를 수행하려면 $idp_host의 admin 사용자 이름과 암호가 있어야 합니다.
절차
관리 콘솔을 열고 admin 사용자 이름과 암호를 입력하여 로그인합니다.
관리 콘솔에 로그인하면 기존 영역이 있습니다. Red Hat Single Sign-On이 먼저 루트 영역을 설정할 때 마스터가 기본적으로 생성됩니다. 이전에 생성된 모든 영역은 관리 콘솔의 왼쪽 상단에 드롭다운 목록에 나열됩니다.
- 영역 드롭다운 목록에서 영역 추가 를 선택합니다.
-
Name 필드에
test_realm
을 입력하고 Create 를 클릭합니다.
3.2.2.2.1. Mellon 서비스 공급자 추가
Red Hat Single Sign-On SAML SP는 클라이언트라고 합니다. SP를 추가하려면 영역의 클라이언트 섹션에 있어야 합니다.
- 왼쪽의 Clients 메뉴 항목을 클릭하고 오른쪽 상단에 있는 만들기를 클릭하여 새 클라이언트를 생성합니다.
3.2.2.2.2. Mellon SP 클라이언트 추가
Mellon SP 클라이언트를 추가하려면 다음 절차를 수행합니다.
절차
- 클라이언트 프로토콜을 SAML으로 설정합니다.
- Client Protocol 드롭다운 목록에서 saml 를 선택합니다.
위에서 만든 Mellon SP 메타데이터 파일을 제공합니다(/etc/httpd/saml2/mellon_metadata.xml).
브라우저가 실행 중인 위치에 따라 브라우저가 파일을 찾을 수 있도록 $sp_host에서 실행 중인 시스템으로 SP 메타데이터를 복사해야 할 수 있습니다.
- 저장을 클릭합니다.
3.2.2.2.3. Mellon SP 클라이언트 편집
중요한 클라이언트 구성 매개변수를 설정하려면 다음 절차를 사용하십시오.
절차
- "Force POST Binding"이 On인지 확인합니다.
- Valid Redirect URI 목록에 paosResponse를 추가합니다.
- "Valid Redirect URI"에 postResponse URL을 복사하여 "+" 아래에 있는 빈 추가 텍스트 필드에 붙여넣습니다.
- "postResponse"를 "paosResponse"로 변경합니다. ( SAML ECP에는 paosResponse URL이 필요합니다.)
- 하단에서 저장 을 클릭합니다.
많은 SAML SP는 그룹의 사용자 멤버십에 따라 권한 부여를 결정합니다. Red Hat Single Sign-On IdP는 사용자 그룹 정보를 관리할 수 있지만 IdP가 SAML 속성으로 제공하도록 구성되지 않은 경우 사용자 그룹을 제공하지 않습니다.
다음 절차에 따라 사용자 그룹을 SAML 속성으로 제공하도록 IdP를 구성합니다.
절차
- 클라이언트의 Mappers 탭을 클릭합니다.
- Mappers 페이지의 오른쪽 상단에서 Create 를 클릭합니다.
- Mapper Type 드롭다운 목록에서 그룹 목록을 선택합니다.
- Name을 "group list"로 설정합니다.
- SAML 특성 이름을 "groups"로 설정합니다.
- 저장을 클릭합니다.
나머지 단계는 $sp_host에서 수행됩니다.
3.2.2.2.4. ID 공급자 메타데이터 검색
이제 IdP의 영역을 생성했으므로 이와 관련된 IdP 메타데이터를 검색해야 하므로 Mellon SP가 이를 인식합니다. 이전에 생성된 /etc/httpd/conf.d/mellon.conf 파일에서 MellonIdPMetadataFile은 /etc/httpd/saml2/idp_metadata.xml로 지정되지만 지금까지 해당 파일이 $sp_host에 존재하지 않습니다.
이 절차를 사용하여 IdP에서 해당 파일을 검색합니다.
절차
$idp_host에 올바른 값을 대체하여 이 명령을 사용하십시오.
curl -k -o /etc/httpd/saml2/idp_metadata.xml \ https://$idp_host/auth/realms/test_realm/protocol/saml/descriptor
curl -k -o /etc/httpd/saml2/idp_metadata.xml \ https://$idp_host/auth/realms/test_realm/protocol/saml/descriptor
Copy to Clipboard Copied! Mellon이 이제 완전히 구성되어 있습니다.
Apache 구성 파일에 대한 구문 검사를 실행하려면 다음 명령을 사용합니다.
apachectl configtest
apachectl configtest
Copy to Clipboard Copied! 참고configtest는 apachectl에 대한 -t 인수와 동일합니다. 구성 테스트에 오류가 표시되면 계속하기 전에 수정합니다.
Apache 서버를 다시 시작하십시오.
systemctl restart httpd.service
systemctl restart httpd.service
Copy to Clipboard Copied!
이제 $idp_host
IdP에 대해 인증하여 SAML SP에서 Red Hat Single Sign-On을 SAML IdP 및 mod_auth_mellon으로 설정했습니다.
4장. Red Hat Single Sign-On을 사용하도록 Docker 레지스트리 설정
Docker 인증은 기본적으로 비활성화되어 있습니다. 사용할 수 있도록 하려면 프로필을 참조하십시오.
이 섹션에서는 Red Hat Single Sign-On을 인증 서버로 사용하도록 Docker 레지스트리를 구성하는 방법에 대해 설명합니다.
Docker 레지스트리를 설정하고 구성하는 방법에 대한 자세한 내용은 Docker 레지스트리 구성 가이드를 참조하십시오.
4.1. Docker 레지스트리 구성 파일 설치
고급 Docker 레지스트리 구성을 사용하는 사용자의 경우 일반적으로 고유한 레지스트리 구성 파일을 제공하는 것이 좋습니다. Red Hat Single Sign-On Docker 공급자는 레지스트리 구성 파일 형식 옵션을 통해 이 메커니즘을 지원합니다. 이 옵션을 선택하면 다음과 유사한 출력이 생성됩니다.
auth: token: realm: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth service: docker-test issuer: http://localhost:8080/auth/realms/master
auth:
token:
realm: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth
service: docker-test
issuer: http://localhost:8080/auth/realms/master
그러면 이 출력을 기존 레지스트리 구성 파일에 복사할 수 있습니다. 파일을 설정하는 방법에 대한 자세한 내용은 레지스트리 구성 파일 사양 을 참조하십시오. 또는 기본 예제로 시작합니다.
Red Hat Single Sign-On 영역의 공개 키 위치로 rootcertbundle
필드를 구성해야 합니다. 이 인수가 없으면 인증 구성이 작동하지 않습니다.
4.2. Docker 레지스트리 환경 변수 설치 덮어쓰기
개발 또는 POC Docker 레지스트리를 위해 간단한 환경 변수 덮어쓰기를 사용하는 것이 적합한 경우가 많습니다. 이 방법은 일반적으로 프로덕션 용도에는 권장되지 않지만 레지스트리를 유지하기 위해 빠르고 디렉터리를 사용해야 하는 경우 유용할 수 있습니다. 클라이언트 설치 탭에서 변수 덮어쓰기 형식 옵션을 사용하기만 하면 출력은 다음과 같이 표시됩니다.
REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth REGISTRY_AUTH_TOKEN_SERVICE: docker-test REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/auth/realms/master
REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth
REGISTRY_AUTH_TOKEN_SERVICE: docker-test
REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/auth/realms/master
Red Hat Single Sign-On 영역의 공개 키 위치로 REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE
덮어쓰기를 구성해야 합니다. 이 인수가 없으면 인증 구성이 작동하지 않습니다.
4.3. Docker Compose YAML 파일
이 설치 방법은 Red Hat Single Sign-On 서버에 대해 docker 레지스트리 인증을 받을 수 있는 쉬운 방법입니다. 개발 목적으로만 사용되며 프로덕션 또는 프로덕션과 유사한 환경에서 사용해서는 안 됩니다.
zip 파일 설치 메커니즘은 Red Hat Single Sign-On 서버가 Docker 레지스트리와 상호 작용하는 방법을 이해하려는 개발자를 위한 빠른 시작 메커니즘을 제공합니다. 구성하려면 다음을 구성합니다.
절차
- 원하는 영역에서 클라이언트 구성을 생성합니다. 이 시점에서 Docker 레지스트리가 없습니다. 빠른 시작에서는 해당 부분을 처리합니다.
- 설치 탭에서 "Docker Compose YAML" 옵션을 선택하고 .zip 파일을 다운로드합니다.
- 아카이브의 압축을 풀고 원하는 위치에 디렉터리를 엽니다.
-
docker-compose up
으로 Docker 레지스트리 시작
HTTP Basic auth flow가 양식이 없기 때문에 'master' 이외의 영역에서 Docker 레지스트리 클라이언트를 구성하는 것이 좋습니다.
위의 구성이 수행되고 keycloak 서버 및 Docker 레지스트리가 실행되면 docker 인증이 성공해야 합니다.
docker login localhost:5000 -u $username
[user ~]# docker login localhost:5000 -u $username
Password: *******
Login Succeeded
5장. 클라이언트 등록 서비스 사용
애플리케이션 또는 서비스에서 Red Hat Single Sign-On을 사용하려면 Red Hat Single Sign-On에 클라이언트를 등록해야 합니다. 관리자는 관리 콘솔(또는 admin REST 엔드포인트)을 통해 이 작업을 수행할 수 있지만 클라이언트는 Red Hat Single Sign-On 클라이언트 등록 서비스를 통해 자체적으로 등록할 수도 있습니다.
클라이언트 등록 서비스는 Red Hat Single Sign-On 클라이언트 담당자, OpenID Connect Client 메타 데이터 및 SAML 엔터티 설명자에 대한 기본 지원을 제공합니다. 클라이언트 등록 서비스 엔드포인트는 /auth/realms/<realm>/clients-registrations/<provider
>입니다.
기본 제공 지원 공급자는
다음과 같습니다.
- 기본값 - Red Hat Single Sign-On Client Representation (JSON)
- 설치 - Red Hat Single Sign-On Adapter Configuration (JSON)
- OpenID-connect - OpenID Connect Client Metadata Description(JSON)
- saml2-entity-descriptor - SAML Entity Descriptor ( XML)
다음 섹션에서는 다양한 공급자를 사용하는 방법에 대해 설명합니다.
5.1. 인증
클라이언트 등록 서비스를 호출하려면 일반적으로 토큰이 필요합니다. 토큰은 전달자 토큰, 초기 액세스 토큰 또는 등록 액세스 토큰일 수 있습니다. 토큰 없이 새 클라이언트를 등록할 수 있는 대안이 있지만 클라이언트 등록 정책을 구성해야 합니다(아래 참조).
5.1.1. 전달자 토큰
전달자 토큰은 사용자 또는 서비스 계정을 대신하여 발행할 수 있습니다. 끝점을 호출하려면 다음 권한이 필요합니다(자세한 내용은 Server Administration Guide 참조).
- create-client 또는 manage-client - 클라이언트 생성
- View-client 또는 manage-client - 클라이언트 보기
- manage-client - 클라이언트를 업데이트 또는 삭제
전달자 토큰을 사용하여 클라이언트를 생성하는 경우 create-client
역할만 사용하여 서비스 계정의 토큰을 사용하는 것이 좋습니다(자세한 내용은 Server Administration Guide 참조).
5.1.2. 초기 액세스 토큰
새 클라이언트를 등록하기 위한 권장 방법은 초기 액세스 토큰을 사용하는 것입니다. 초기 액세스 토큰은 클라이언트를 생성하는 데만 사용할 수 있으며 구성 가능한 만료와 생성할 수 있는 클라이언트 수에 대한 구성 가능한 제한이 있습니다.
초기 액세스 토큰은 관리 콘솔을 통해 생성할 수 있습니다. 새 초기 액세스 토큰을 생성하려면 먼저 관리 콘솔의 영역을 선택한 다음 왼쪽의 메뉴에서 settings를 클릭한 다음 페이지에 표시된 탭에 있는 클라이언트 등록이
표시됩니다. 그런 다음
Initial Access Tokens
하위 탭을 클릭합니다.
이제 기존 초기 액세스 토큰을 볼 수 있습니다. 액세스 권한이 있는 경우 더 이상 필요하지 않은 토큰을 삭제할 수 있습니다. 토큰을 생성할 때만 토큰 값을 검색할 수 있습니다. 새 토큰을 생성하려면 생성을
클릭합니다. 토큰을 사용하여 생성할 수 있는 클라이언트 수를 선택적으로 추가할 수 있습니다. 저장
을 클릭하면 토큰 값이 표시됩니다.
나중에 검색할 수 없으므로 지금 이 토큰을 복사하거나 붙여 넣는 것이 중요합니다. 복사/붙여넣기를 잊어 버린 경우 토큰을 삭제하고 다른 토큰을 생성합니다.
토큰 값은 클라이언트 등록 서비스를 호출할 때 요청의 Authorization 헤더에 추가하여 표준 전달자 토큰으로 사용됩니다. 예를 들면 다음과 같습니다.
Authorization: bearer eyJhbGciOiJSUz...
Authorization: bearer eyJhbGciOiJSUz...
5.1.3. 등록 액세스 토큰
클라이언트 등록 서비스를 통해 클라이언트를 생성하면 응답에 등록 액세스 토큰이 포함됩니다. 등록 액세스 토큰에서는 나중에 클라이언트 구성을 검색할 수 있는 액세스 권한을 제공하지만 클라이언트를 업데이트하거나 삭제할 수도 있습니다. 등록 액세스 토큰은 전달자 토큰 또는 초기 액세스 토큰과 동일한 방식으로 요청에 포함됩니다. 등록 액세스 토큰은 응답에 사용되는 경우 새 토큰이 포함된 한 번만 유효합니다.
클라이언트 등록 서비스 외부에서 클라이언트를 생성한 경우 연결된 등록 액세스 토큰이 없습니다. 관리 콘솔을 통해 이를 생성할 수 있습니다. 이는 특정 클라이언트의 토큰을 손실한 경우에도 유용할 수 있습니다. 새 토큰을 생성하려면 관리 콘솔에서 클라이언트를 찾고 자격 증명을
클릭합니다. 그런 다음 Generate registration access token
을 클릭합니다.
5.2. Red Hat Single Sign-On 담당자
기본
클라이언트 등록 공급자를 사용하여 클라이언트를 생성, 검색, 업데이트 및 삭제할 수 있습니다. 이는 프로토콜 매퍼 구성을 포함하여 관리 콘솔을 통해 클라이언트 구성을 정확하게 수행할 수 있는 Red Hat Single Sign-On Client Representation 형식을 사용합니다.
클라이언트에서 JSON(Client Representation)을 생성하려면 /auth/realms/<realm>/clients-registrations/default
에 대한 HTTP POST 요청을 수행합니다.
등록 액세스 토큰도 포함하는 클라이언트 담당자를 반환합니다. 나중에 클라이언트를 검색하거나 업데이트하거나 삭제하려는 경우 등록 액세스 토큰을 위치에 저장해야 합니다.
클라이언트 담당자를 검색하려면 /auth/realms/<realm>/clients-registrations/default/<client id
>에 대한 HTTP GET 요청을 수행합니다.
또한 새로운 등록 액세스 토큰을 반환합니다.
클라이언트 담당자를 업데이트하려면 업데이트된 클라이언트 담당자를 사용하여 HTTP PUT 요청을 /auth/realms/<realm>/clients-registrations/default/<client id
>로 수행합니다.
또한 새로운 등록 액세스 토큰을 반환합니다.
클라이언트 담당자를 삭제하려면 다음과 같이 HTTP DELETE 요청을 수행합니다. /auth/realms/<realm>/clients-registrations/default/<client id
>
5.3. Red Hat Single Sign-On 어댑터 구성
설치
클라이언트 등록 공급자를 사용하여 클라이언트의 어댑터 구성을 검색할 수 있습니다. 토큰 인증 외에도 HTTP 기본 인증을 사용하여 클라이언트 자격 증명으로 인증할 수도 있습니다. 이를 위해 요청에 다음 헤더를 포함합니다.
Authorization: basic BASE64(client-id + ':' + client-secret)
Authorization: basic BASE64(client-id + ':' + client-secret)
어댑터 구성을 검색하려면 /auth/realms/<realm>/clients-registrations/install/<client id
>에 HTTP GET 요청을 수행합니다.
공용 클라이언트에 인증이 필요하지 않습니다. 즉, JavaScript 어댑터의 경우 위의 URL을 사용하여 Red Hat Single Sign-On에서 직접 클라이언트 구성을 로드할 수 있습니다.
5.4. OpenID Connect 동적 클라이언트 등록
Red Hat Single Sign-On은 OAuth 2.0 동적 클라이언트 등록 프로토콜 및 OAuth 2.0 동적 클라이언트 등록 관리 프로토콜을 확장하는 OpenID Connect 동적 클라이언트 등록 등록을 구현합니다.
이러한 사양을 사용하여 Red Hat Single Sign-On에 클라이언트를 등록하는 끝점은 /auth/realms/<realm>/clients-registrations/openid-connect[/<client id>]
입니다.
이 엔드포인트는 영역의 OpenID Connect Discovery 끝점인 /auth/realms/<realm>/.well-known/openid-configuration
에서도 찾을 수 있습니다.
5.5. SAML 엔터티 설명자
SAML Entity Descriptor 엔드포인트는 SAML v2 Entity Descriptors만 사용하여 클라이언트를 생성할 수 있습니다. 클라이언트 검색, 업데이트 또는 삭제를 지원하지 않습니다. 이러한 작업에서는 Red Hat Single Sign-On 표현 끝점을 사용해야 합니다. 클라이언트를 생성할 때 Red Hat Single Sign-On Client Representation은 등록 액세스 토큰을 포함하여 생성된 클라이언트에 대한 세부 정보와 함께 반환됩니다.
클라이언트가 SAML Entity Descriptor를 사용하여 /auth/realms/<realm>/clients-registrations/saml2-entity-descriptor
로 HTTP POST 요청을 생성하려면 다음을 수행합니다.
5.6. CURL 사용 예
다음 예제에서는 CURL을 사용하여 clientId myclient
가 있는 클라이언트를 생성합니다. eyJhbGciOiJSUz…
를 적절한 초기 액세스 토큰 또는 전달자 토큰으로 교체해야 합니다.
curl -X POST \ -d '{ "clientId": "myclient" }' \ -H "Content-Type:application/json" \ -H "Authorization: bearer eyJhbGciOiJSUz..." \ http://localhost:8080/auth/realms/master/clients-registrations/default
curl -X POST \
-d '{ "clientId": "myclient" }' \
-H "Content-Type:application/json" \
-H "Authorization: bearer eyJhbGciOiJSUz..." \
http://localhost:8080/auth/realms/master/clients-registrations/default
5.7. Java 클라이언트 등록 API 사용 예
Java API를 사용하면 Java를 사용하여 클라이언트 등록 서비스를 쉽게 사용할 수 있습니다. 을 사용하여 Maven의 종속성 org.keycloak:keycloak-client-registration-api:>VERSION
<
클라이언트 등록 사용에 대한 자세한 내용은 JavaDocs를 참조하십시오. 다음은 클라이언트를 생성하는 예입니다. eyJhbGciOiJSUz…
를 적절한 초기 액세스 토큰 또는 전달자 토큰으로 교체해야 합니다.
String token = "eyJhbGciOiJSUz..."; ClientRepresentation client = new ClientRepresentation(); client.setClientId(CLIENT_ID); ClientRegistration reg = ClientRegistration.create() .url("http://localhost:8080/auth", "myrealm") .build(); reg.auth(Auth.token(token)); client = reg.create(client); String registrationAccessToken = client.getRegistrationAccessToken();
String token = "eyJhbGciOiJSUz...";
ClientRepresentation client = new ClientRepresentation();
client.setClientId(CLIENT_ID);
ClientRegistration reg = ClientRegistration.create()
.url("http://localhost:8080/auth", "myrealm")
.build();
reg.auth(Auth.token(token));
client = reg.create(client);
String registrationAccessToken = client.getRegistrationAccessToken();
5.8. 클라이언트 등록 정책
현재 계획은 서버 관리 가이드에 설명된 클라이언트 정책을 대신하여 클라이언트 등록 정책을 제거하기 위한 계획입니다. 클라이언트 정책은 보다 유연하고 더 많은 사용 사례를 지원합니다.
Red Hat Single Sign-On은 현재 클라이언트 등록 서비스를 통해 새로운 클라이언트를 등록하는 방법에 대해 두 가지 방법을 지원합니다.
-
인증 요청 - 새 클라이언트 등록을 요청하려면 위에서 언급한 것처럼
Initial Access Token
또는Bearer 토큰
을 포함해야 합니다. - 익명 요청 - 새 클라이언트 등록을 요청해도 토큰을 포함할 필요가 없습니다.
익명 클라이언트 등록 요청은 매우 흥미로운 기능이지만 일반적으로 누군가가 제한없이 새로운 클라이언트를 등록하는 것을 원하지 않습니다. 따라서 클라이언트 등록 정책 SPI
가 있으므로 새 고객을 등록할 수 있는 사용자와 어떤 조건에서도 제한할 수 있습니다.
Red Hat Single Sign-On 관리 콘솔에서 클라이언트 등록 탭을 클릭한 다음
하위 탭을 클릭할 수 있습니다. 여기에서 익명 요청에 대해 기본적으로 구성된 정책과 인증된 요청에 대해 어떤 정책을 구성하는지 확인할 수 있습니다.
클라이언트 등록
정책
익명 요청( 토큰이 없는 요청)은 새 클라이언트를 생성(등록)하는 경우에만 허용됩니다. 따라서 익명 요청을 통해 새 클라이언트를 등록할 때 응답에는 특정 클라이언트의 읽기, 업데이트 또는 삭제 요청에 사용해야 하는 등록 액세스 토큰이 포함됩니다. 그러나 익명 등록 등록에서 이 등록 액세스 토큰을 사용하는 경우 익명의 정책에도 적용됩니다! 즉, 신뢰할 수 있는 호스트 정책이 있는 경우 업데이트 클라이언트 요청도 신뢰할 수 있는 호스트에서 가져와야
합니다. 예를 들어 클라이언트를 업데이트할 때, Consent Required
정책이 존재하는 경우 Consent Required
를 비활성화할 수 없습니다.
현재 다음과 같은 정책 구현을 제공합니다.
-
신뢰할 수 있는 호스트 정책 - 신뢰할 수 있는 호스트 및 신뢰할 수 있는 도메인 목록을 구성할 수 있습니다. 클라이언트 등록 서비스에 대한 요청은 해당 호스트 또는 도메인에서만 보낼 수 있습니다. 신뢰할 수 없는 일부 IP에서 전송된 요청은 거부됩니다. 새로 등록된 클라이언트의 URL도 해당 신뢰할 수 있는 호스트 또는 도메인만 사용해야 합니다. 예를 들어 신뢰할 수 없는 일부 호스트를 가리키는 클라이언트의
리디렉션 URI
를 설정할 수 없습니다. 기본적으로 허용 목록에 있는 호스트가 없으므로 익명 클라이언트 등록이 비활성화되었습니다. -
동의 필수 정책 - 새로 등록된 고객은
Consent Allowed
스위치를 사용하도록 설정합니다. 따라서 인증이 성공하면 사용자는 권한(클라이언트 범위)을 승인해야 할 때 항상 동의 화면을 볼 수 있습니다. 이는 사용자가 승인하지 않는 한 고객은 개인 정보 또는 사용자의 권한에 액세스할 수 없음을 의미합니다. - 프로토콜 매퍼 정책 - 허용 목록에 있는 프로토콜 매퍼 구현 목록을 구성할 수 있습니다. 화이트리스트가 없는 프로토콜 매퍼가 포함된 경우 새 클라이언트를 등록하거나 업데이트할 수 없습니다. 이 정책은 인증된 요청에도 사용되므로 인증된 요청에도 사용할 수 있는 프로토콜 매퍼가 몇 가지 제한 사항이 있습니다.
-
클라이언트 범위 정책 - 새로 등록되거나 업데이트된 클라이언트와 함께 사용할 수 있는
클라이언트
범위를 허용 목록에 추가할 수 있습니다. 기본적으로 허용 가능한 범위는 없습니다. CloudEvent 기본 클라이언트 범위로 정의되는클라이언트 범위만 기본적으로
허용 목록에 표시됩니다. -
전체 범위 정책 - 새로 등록된 클라이언트에는
전체 범위 허용
스위치가 비활성화됩니다. 즉, 다른 클라이언트의 범위 영역 역할 또는 클라이언트 역할이 없습니다. - Max Clients Policy - 해당 영역의 현재 클라이언트 수가 지정된 제한보다 크거나 같은 경우 등록을 거부합니다. 기본적으로 익명 등록의 경우 200입니다.
- 클라이언트 비활성화 정책 - 새로 등록된 클라이언트가 비활성화됩니다. 즉, 관리자는 새로 등록된 모든 클라이언트를 수동으로 승인하고 활성화해야 합니다. 이 정책은 익명 등록에도 기본적으로 사용되지 않습니다.
6장. CLI를 사용하여 클라이언트 등록 자동화
클라이언트 등록 CLI는 애플리케이션 개발자가 Red Hat Single Sign-On과 통합할 때 셀프서비스 방식으로 새 클라이언트를 구성할 수 있는 CLI(명령줄 인터페이스) 툴입니다. Red Hat Single Sign-On 클라이언트 등록 REST 엔드포인트와 상호 작용하도록 특별히 설계되었습니다.
Red Hat Single Sign-On을 사용하려면 모든 애플리케이션이 클라이언트 구성을 생성하거나 받아야 합니다. 일반적으로 고유한 호스트 이름에 호스팅되는 각 새 애플리케이션에 대해 새 클라이언트를 구성합니다. 애플리케이션이 Red Hat Single Sign-On과 상호 작용할 때 애플리케이션은 클라이언트 ID로 식별되므로 Red Hat Single Sign-On에서 로그인 페이지, SSO(Single Sign-On) 세션 관리 및 기타 서비스를 제공할 수 있습니다.
클라이언트 등록 CLI를 사용하여 명령줄에서 애플리케이션 클라이언트를 구성할 수 있으며 쉘 스크립트에서 사용할 수 있습니다.
특정 사용자가 클라이언트 등록 CLI
를 사용할 수 있도록 Red Hat Single Sign-On 관리자는 일반적으로 Admin Console을 사용하여 새 사용자를 적절한 역할로 구성하거나 클라이언트 등록 REST API에 대한 액세스 권한을 부여하도록 새 클라이언트 및 클라이언트 시크릿을 구성합니다.
6.1. 클라이언트 등록 CLI에서 사용할 새 일반 사용자 구성
절차
-
관리자 콘솔에 로그인합니다(예: http://localhost:8080/auth/admin)
admin
. - 관리할 영역을 선택합니다.
- 기존 사용자를 사용하려면 편집할 사용자를 선택합니다. 그렇지 않으면 새 사용자를 만듭니다.
-
Role Mappings > Client Roles > realm-management 를 선택합니다. 마스터 영역에 있는 경우 NAME-realm 을 선택합니다. 여기서
NAME
은 대상 영역의 이름입니다. 다른 영역에 대한 액세스 권한을 마스터 영역의 사용자에게 부여할 수 있습니다. Available Roles > manage-client 를 선택하여 전체 클라이언트 관리 권한 세트를 부여합니다. 또 다른 옵션은 읽기 전용 또는 create -client 에 대해 view -client를 선택하여 새 클라이언트를 만드는 것입니다.
참고이러한 권한은 Initial Access Token 또는 등록 액세스 토큰을 사용하지 않고 작업을 수행할 수 있는 기능을 사용자에게 부여합니다.
사용자에게 영역 관리
역할을 할당할 수 없습니다. 이 경우 사용자는 여전히 클라이언트 등록 CLI로 로그인할 수 있지만 Initial Access Token 없이는 사용할 수 없습니다. 토큰 없이 작업을 수행하려고 하면 403 Forbidden 오류가 발생합니다.
관리자는 Admin Console에서 Initial Access Tokens을 발행할 수 있습니다. settings > Client registration > Initial Access Token 메뉴를 통해 액세스할 수 있습니다.
6.2. 클라이언트 등록 CLI와 함께 사용할 클라이언트 구성
기본적으로 서버는 클라이언트 등록 CLI를 admin-cli
클라이언트로 인식합니다. 이 클라이언트는 모든 새 영역에 대해 자동으로 구성됩니다. 사용자 이름으로 로그인할 때 추가 클라이언트 구성이 필요하지 않습니다.
절차
-
클라이언트 등록 CLI에 별도의 클라이언트 구성을 사용하려면 클라이언트(예:
reg-cli
)를 생성합니다. - 표준 흐름 활성화 설정을 Off 로 전환합니다.
클라이언트
액세스 유형을
기밀성으로 구성하고 자격 증명 >
; ClientId 및 Secret 을 선택하여 보안을 강화합니다.참고인증 정보 탭에서
클라이언트 ID 및 시크릿
또는서명 JWT
를 구성할 수 있습니다.Admin Console
의 클라이언트 섹션에서 편집할 클라이언트를 선택하여 클라이언트와 연결된 서비스 계정을 사용하려면 서비스 계정을 활성화합니다.- Settings 아래에서 액세스 유형을 기밀성 으로 변경하고 서비스 계정 활성화 설정을 On 으로 전환한 다음 저장 을 클릭합니다.
- 서비스 계정 역할을 클릭하고 원하는 역할을 선택하여 서비스 계정에 대한 액세스를 구성합니다. 선택할 역할에 대한 자세한 내용은 6.1절. “클라이언트 등록 CLI에서 사용할 새 일반 사용자 구성” 을 참조하십시오.
- 서비스 계정 대신 일반 사용자 계정을 사용하려면 Direct Access Grants Enabled 설정을 On 으로 전환합니다.
-
클라이언트가 기밀성으로 구성된 경우
--secret
옵션을 사용하여kcreg 구성 인증 정보를
실행할 때 구성된 시크릿을 제공합니다. -
kcreg 구성 자격 증명을 실행할 때 사용할
)를 지정합니다.clientId
(예:--client reg
-cli -
서비스 계정을 활성화하면
kcreg 구성 인증
정보를 실행할 때 사용자 지정을 생략하고 클라이언트 시크릿 또는 키 저장소 정보만 제공할 수 있습니다.
6.3. 클라이언트 등록 CLI 설치
클라이언트 등록 CLI는 Red Hat Single Sign-On Server 배포 내에 패키지로 제공됩니다. bin
디렉터리 내에서 실행 스크립트를 찾을 수 있습니다. Linux 스크립트는 kcreg.sh
라고 하며 Windows 스크립트는 kcreg.vdd라고 합니다
.
파일 시스템의 모든 위치에서 사용할 클라이언트를 설정할 때 Red Hat Single Sign-On 서버 디렉터리를 PATH
에 추가합니다.
예를 들면 다음과 같습니다.
- Linux:
export PATH=$PATH:$KEYCLOAK_HOME/bin kcreg.sh
$ export PATH=$PATH:$KEYCLOAK_HOME/bin
$ kcreg.sh
- Windows:
set PATH=%PATH%;%KEYCLOAK_HOME%\bin kcreg
c:\> set PATH=%PATH%;%KEYCLOAK_HOME%\bin
c:\> kcreg
KEYCLOAK_HOME
은 Red Hat Single Sign-On 서버 배포가 압축 해제된 디렉터리를 나타냅니다.
6.4. 클라이언트 등록 CLI 사용
절차
- 자격 증명으로 로그인하여 인증된 세션을 시작합니다.
클라이언트 등록 REST
끝점에서 명령을 실행합니다.예를 들면 다음과 같습니다.
Linux:
kcreg.sh config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli kcreg.sh create -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]' kcreg.sh get my_client
$ kcreg.sh config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli $ kcreg.sh create -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]' $ kcreg.sh get my_client
Copy to Clipboard Copied! Windows:
kcreg config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli kcreg create -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]" kcreg get my_client
c:\> kcreg config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli c:\> kcreg create -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]" c:\> kcreg get my_client
Copy to Clipboard Copied! 참고프로덕션 환경에서 네트워크 스니퍼에 토큰이 노출되지 않도록
https
를 사용하여 Red Hat Single Sign-On에 액세스해야 합니다.
Java의 기본 인증서 신뢰 저장소에 포함된 신뢰할 수 있는 CA(인증 기관) 중 하나에서 서버의 인증서를 발급하지 않은 경우
truststore.jks
파일을 준비하고 클라이언트 등록 CLI에 이를 사용하도록 지시합니다.예를 들면 다음과 같습니다.
Linux:
kcreg.sh config truststore --trustpass $PASSWORD ~/.keycloak/truststore.jks
$ kcreg.sh config truststore --trustpass $PASSWORD ~/.keycloak/truststore.jks
Copy to Clipboard Copied! Windows:
kcreg config truststore --trustpass %PASSWORD% %HOMEPATH%\.keycloak\truststore.jks
c:\> kcreg config truststore --trustpass %PASSWORD% %HOMEPATH%\.keycloak\truststore.jks
Copy to Clipboard Copied!
6.4.1. 로그인
절차
- 클라이언트 등록 CLI로 로그인할 때 서버 끝점 URL과 영역을 지정합니다.
-
사용자 이름 또는 클라이언트 ID를 지정하여 특수 서비스 계정을 사용합니다. 사용자 이름을 사용하는 경우 지정된 사용자의 암호를 사용해야 합니다. 클라이언트 ID를 사용하는 경우 암호 대신 클라이언트 시크릿 또는
서명 JWT
를 사용합니다.
로그인 방법에 관계없이 로그인하는 계정에는 클라이언트 등록 작업을 수행할 수 있는 적절한 권한이 필요합니다. 마스터가 아닌 영역에 있는 모든 계정에는 동일한 영역 내의 클라이언트를 관리할 수 있는 권한만 가질 수 있습니다. 다른 영역을 관리해야 하는 경우 다른 영역에서 여러 사용자를 구성하거나 마스터
영역에 단일 사용자를 생성하고 다른 영역에서 클라이언트를 관리하는 역할을 추가할 수 있습니다.
클라이언트 등록 CLI로 사용자를 구성할 수 없습니다. 관리 콘솔 웹 인터페이스 또는 관리 클라이언트 CLI를 사용하여 사용자를 구성합니다. 자세한 내용은 서버 관리 가이드를 참조하십시오.
kcreg
가 성공적으로 로그인하면 권한 부여 토큰을 수신하여 개인 구성 파일에 저장하므로 후속 호출에 토큰을 사용할 수 있습니다. 구성 파일에 대한 자세한 내용은 6.4.2절. “대체 구성 작업” 을 참조하십시오.
클라이언트 등록 CLI 사용에 대한 자세한 내용은 기본 도움말을 참조하십시오.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh help
$ kcreg.sh help
- Windows:
kcreg help
c:\> kcreg help
인증된 세션을 시작하는 방법에 대한 자세한 내용은 kcreg config credentials --help
를 참조하십시오.
6.4.2. 대체 구성 작업
기본적으로 클라이언트 등록 CLI는 사용자의 홈 디렉터리에 있는 기본 위치 ./.keycloak/kcreg.config
에서 구성 파일을 자동으로 유지합니다. --config
옵션을 사용하여 다른 파일 또는 위치를 가리켜 인증된 여러 세션을 병렬로 유지 관리할 수 있습니다. 단일 스레드에서 단일 구성 파일에 연결된 작업을 수행하는 가장 안전한 방법입니다.
구성 파일이 시스템의 다른 사용자에게 표시되도록 하지 마십시오. 구성 파일에는 비공개로 유지해야 하는 액세스 토큰과 시크릿이 포함되어 있습니다.
편리하지 않고 더 많은 토큰 요청이 필요한 경우에도 모든 명령에 --no-config
옵션을 사용하여 구성 파일에 시크릿을 저장하지 않도록 할 수 있습니다. 각 kcreg
호출을 사용하여 모든 인증 정보를 지정합니다.
6.4.3. 초기 액세스 및 등록 액세스 토큰
사용하려는 Red Hat Single Sign-On 서버에 계정이 구성되어 있지 않은 개발자는 클라이언트 등록 CLI를 사용할 수 있습니다. 이는 영역 관리자가 개발자에게 Initial Access Token을 발행하는 경우에만 가능합니다. 영역 관리자는 이러한 토큰을 발행하고 배포하는 방법을 결정할 수 있습니다. 영역 관리자는 Initial Access Token의 최대 기간과 이를 사용하여 생성할 수 있는 총 클라이언트 수를 제한할 수 있습니다.
개발자에게 Initial Access Token이 있으면 개발자는 kcreg 구성 자격 증명을
사용하여 인증하지 않고 새 클라이언트를 생성하는 데 사용할 수 있습니다. Initial Access Token은 구성 파일에 저장되거나 kcreg create
명령의 일부로 지정할 수 있습니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh config initial-token $TOKEN kcreg.sh create -s clientId=myclient
$ kcreg.sh config initial-token $TOKEN
$ kcreg.sh create -s clientId=myclient
또는
kcreg.sh create -s clientId=myclient -t $TOKEN
$ kcreg.sh create -s clientId=myclient -t $TOKEN
- Windows:
kcreg config initial-token %TOKEN% kcreg create -s clientId=myclient
c:\> kcreg config initial-token %TOKEN%
c:\> kcreg create -s clientId=myclient
또는
kcreg create -s clientId=myclient -t %TOKEN%
c:\> kcreg create -s clientId=myclient -t %TOKEN%
Initial Access Token을 사용하는 경우 서버 응답에 새로 발행된 등록 액세스 토큰이 포함됩니다. 해당 클라이언트의 후속 작업은 해당 클라이언트에만 유효한 해당 토큰으로 인증하여 수행해야 합니다.
클라이언트 등록 CLI는 개인 구성 파일을 자동으로 사용하여 이 토큰을 저장하고 관련 클라이언트와 함께 사용합니다. 모든 클라이언트 작업에 동일한 구성 파일을 사용하는 한 개발자가 이러한 방식으로 생성된 클라이언트를 읽기, 업데이트 또는 삭제할 필요가 없습니다.
Initial Access 및 등록 액세스 토큰에 대한 자세한 내용은 클라이언트 등록을 참조하십시오.
클라이언트 등록 CLI로 토큰을 구성하는 방법에 대한 자세한 내용은 kcreg 구성 initial-token --help
및 kcreg config registration-token --help
명령을 실행합니다.
6.4.4. 클라이언트 구성 생성
자격 증명을 사용하여 인증하거나 Initial Access Token을 구성한 후 첫 번째 작업은 일반적으로 새 클라이언트를 생성하는 것입니다. 준비된 JSON 파일을 템플릿으로 사용하고 일부 속성을 설정하거나 재정의하는 경우가 많습니다.
다음 예제에서는 JSON 파일을 읽고, 포함할 수 있는 클라이언트 ID를 재정의하고, 다른 속성을 설정하고, 성공적으로 생성된 후 구성을 표준 출력에 출력하는 방법을 보여줍니다.
- Linux:
kcreg.sh create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s 'redirectUris=["/myclient/*"]' -o
$ kcreg.sh create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s 'redirectUris=["/myclient/*"]' -o
- Windows:
kcreg create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s "redirectUris=[\"/myclient/*\"]" -o
C:\> kcreg create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s "redirectUris=[\"/myclient/*\"]" -o
kcreg create
명령에 대한 자세한 내용은 kcreg create --help
를 실행합니다.
kcreg attrs
를 사용하여 사용 가능한 특성을 나열할 수 있습니다. 많은 구성 속성은 유효성 또는 일관성이 확인되지 않습니다. 적절한 값을 지정해야 합니다. 템플릿에 id 필드가 없어야 하며 kcreg create
명령에 대한 인수로 지정하지 않아야 합니다.
6.4.5. 클라이언트 구성 검색
kcreg get
명령을 사용하여 기존 클라이언트를 검색할 수 있습니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh get myclient
$ kcreg.sh get myclient
- Windows:
kcreg get myclient
C:\> kcreg get myclient
웹 애플리케이션으로 패키지할 수 있는 어댑터 구성 파일로 클라이언트 구성을 검색할 수도 있습니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh get myclient -e install > keycloak.json
$ kcreg.sh get myclient -e install > keycloak.json
- Windows:
kcreg get myclient -e install > keycloak.json
C:\> kcreg get myclient -e install > keycloak.json
kcreg get
명령에 대한 자세한 내용은 kcreg get --help
명령을 실행합니다.
6.4.6. 클라이언트 구성 수정
클라이언트 구성을 업데이트하는 방법은 두 가지가 있습니다.
한 가지 방법은 현재 구성을 가져와서 파일에 저장하고 편집한 후 서버에 완전히 새 상태를 다시 게시하는 것입니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh get myclient > myclient.json vi myclient.json kcreg.sh update myclient -f myclient.json
$ kcreg.sh get myclient > myclient.json
$ vi myclient.json
$ kcreg.sh update myclient -f myclient.json
- Windows:
kcreg get myclient > myclient.json notepad myclient.json kcreg update myclient -f myclient.json
C:\> kcreg get myclient > myclient.json
C:\> notepad myclient.json
C:\> kcreg update myclient -f myclient.json
두 번째 방법은 현재 클라이언트를 가져오고, 필드를 설정하거나 삭제하고, 한 단계로 다시 게시합니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh update myclient -s enabled=false -d redirectUris
$ kcreg.sh update myclient -s enabled=false -d redirectUris
- Windows:
kcreg update myclient -s enabled=false -d redirectUris
C:\> kcreg update myclient -s enabled=false -d redirectUris
또한 적용할 변경 사항만 포함하는 파일을 사용할 수 있으므로 너무 많은 값을 인수로 지정할 필요가 없습니다. 이 경우 --merge
를 지정하여 JSON 파일을 전체 새 구성으로 처리하는 대신 기존 구성에 적용할 속성 세트로 처리해야 합니다.
예를 들면 다음과 같습니다.
- Linux:
kcreg.sh update myclient --merge -d redirectUris -f mychanges.json
$ kcreg.sh update myclient --merge -d redirectUris -f mychanges.json
- Windows:
kcreg update myclient --merge -d redirectUris -f mychanges.json
C:\> kcreg update myclient --merge -d redirectUris -f mychanges.json
kcreg update --help
명령을 실행하여 kcreg update
명령에 대한 자세한 내용을 확인합니다.
6.4.7. 클라이언트 구성 삭제
다음 예제를 사용하여 클라이언트를 삭제합니다.
- Linux:
kcreg.sh delete myclient
$ kcreg.sh delete myclient
- Windows:
kcreg delete myclient
C:\> kcreg delete myclient
kcreg delete
명령에 대한 자세한 내용은 kcreg delete --help
명령을 실행합니다.
6.4.8. 잘못된 등록 액세스 토큰 새로 고침
--no-config
모드를 사용하여 생성, 읽기, 업데이트 및 삭제(CRUD) 작업을 수행할 때 클라이언트 등록 CLI에서 등록 액세스 토큰을 처리할 수 없습니다. 이 경우 클라이언트의 가장 최근에 발행된 등록 액세스 토큰을 추적할 수 있으므로 관리 클라이언트 권한이 있는 계정으로 인증하지 않고 해당 클라이언트에서 추가 CRUD 작업을 수행할 수 없습니다.
권한이 있는 경우 클라이언트의 새 등록 액세스 토큰을 발행하여 표준 출력에 출력하거나 선택한 구성 파일에 저장할 수 있습니다. 그렇지 않으면 영역 관리자에게 클라이언트에 대한 새 등록 액세스 토큰을 발행하여 전송하도록 요청해야 합니다. 그런 다음 --token
옵션을 통해 모든 CRUD 명령에 전달할 수 있습니다. kcreg 구성 registration-token
명령을 사용하여 새 토큰을 구성 파일에 저장하고 해당 시점에서 클라이언트 등록 CLI에서 자동으로 처리할 수 있습니다.
kcreg update-token --help
명령에 대한 자세한 내용을 확인하려면 kcreg update-token
--help 명령을 실행합니다.
6.5. 문제 해결
Q: 로그인할 때 Parameter client_assertion_type is missing [invalid_client] 오류가 표시됩니다.
A: 이 오류는 클라이언트가
서명된 JWT
토큰 자격 증명으로 구성되었음을 나타냅니다. 즉, 로그인할 때--keystore
매개변수를 사용해야 합니다.
7장. 토큰 교환 사용
토큰 교환은 기술 프리뷰 이며 완전히 지원되지 않습니다. 이 기능은 기본적으로 비활성화되어 있습니다.
-Dkeycloak.profile=preview
또는 -Dkeycloak.profile.feature.token_exchange=enabled
로 서버를 시작하려면 다음을 수행하십시오. 자세한 내용은 프로필을 참조하십시오.
토큰 교환을 사용하려면 token_exchange
기능도 활성화해야 합니다. 프로필 을 참조하십시오.
7.1. 토큰 교환 방식
Red Hat Single Sign-On에서 토큰 교환은 완전히 다른 토큰을 얻기 위해 자격 증명 또는 토큰 세트를 사용하는 프로세스입니다. 클라이언트는 신뢰할 수 없는 애플리케이션에서 호출해야 하므로 현재 토큰을 다운그레이드할 수 있습니다. 클라이언트는 연결된 소셜 공급자 계정에 저장된 토큰에 대해 Red Hat Single Sign-On 토큰을 교환할 수 있습니다. 다른 Red Hat Single Sign-On 영역 또는 외부 IDP에서 Mint한 외부 토큰을 신뢰할 수 있습니다. 클라이언트는 사용자를 가장해야 할 수 있습니다. 다음은 토큰 교환과 관련된 Red Hat Single Sign-On의 현재 기능에 대한 간략한 요약입니다.
- 클라이언트는 다른 클라이언트를 대상으로 하는 새 토큰을 위해 특정 클라이언트에 대해 생성된 기존 Red Hat Single Sign-On 토큰을 교환할 수 있습니다.
- 클라이언트는 기존 Red Hat Single Sign-On 토큰을 외부 토큰(예: 연결된 Facebook 계정)으로 교환할 수 있습니다.
- 클라이언트는 Red Hat Single Sign-On 토큰의 외부 토큰을 교환할 수 있습니다.
- 클라이언트가 사용자 가장할 수 있습니다.
Red Hat Single Sign-On의 토큰 교환은 IETF에서 OAuth 토큰 교환 사양 구현이 매우 느렸습니다. 이를 약간 연장하고, 일부를 무시하며, 사양의 다른 부분을 느슨하게 해석했습니다. 영역의 OpenID Connect 토큰 끝점에서 간단한 부여 유형 호출입니다.
/auth/realms/{realm}/protocol/openid-connect/token
/auth/realms/{realm}/protocol/openid-connect/token
양식 매개변수(application/x-www-form-urlencoded
)를 입력으로 허용하며 출력은 교환을 요청한 토큰 유형에 따라 다릅니다. 토큰 교환은 클라이언트 끝점이므로 요청이 호출 클라이언트에 대한 인증 정보를 제공해야 합니다. 공용 클라이언트는 클라이언트 ID를 form 매개 변수로 지정합니다. 기밀 클라이언트는 양식 매개 변수를 사용하여 클라이언트 ID 및 시크릿, 기본 인증, 기본 인증을 전달할 수도 있지만 관리자가 해당 영역에 클라이언트 인증 흐름을 구성했습니다.
7.1.1. 매개 변수 양식
- client_id
- 필수 항목인. 이 매개변수는 인증에 양식 매개 변수를 사용하는 클라이언트에 필요합니다. Basic Auth, 클라이언트 JWT 토큰 또는 클라이언트 인증서 인증을 사용하는 경우 이 매개변수를 지정하지 마십시오.
- client_secret
- 필수 항목인. 이 매개변수는 인증에 양식 매개 변수를 사용하고 클라이언트 시크릿을 자격 증명으로 사용하는 클라이언트에 필요합니다. 영역의 클라이언트 호출이 다른 방법으로 인증되는 경우 이 매개 변수를 지정하지 마십시오.
- grant_type
-
필수 항목입니다. 매개변수 값은
urn:ietf:params:oauth:grant-type:token-exchange
이어야 합니다. - subject_token
- 선택사항입니다. 요청이 이루어진 당사자의 ID를 나타내는 보안 토큰입니다. 새 토큰의 기존 토큰을 교환하는 경우 필요합니다.
- subject_issuer
-
선택사항입니다.
subject_token
의 발급자를 식별합니다. 토큰이 현재 영역에서 가져오거나subject_token_type
에서 발행자를 결정할 수 있는 경우 비워 둘 수 있습니다. 그렇지 않으면 이를 지정해야 합니다. 유효한 값은 영역에 대해 구성된ID 공급자
의 별칭입니다. 또는 특정ID 공급자에 의해 구성된 발행자 클레임 식별자입니다
. - subject_token_type
-
선택사항입니다. 이 매개변수는
subject_token
매개변수와 함께 전달되는 토큰의 유형입니다.subject_token
이 영역에서 제공되며 액세스 토큰인 경우 기본값은urn:ietf:params:oauth:token-type:access_token
입니다. 외부 토큰인 경우subject_issuer
의 요구 사항에 따라 이 매개 변수를 지정하거나 지정하지 않아도 됩니다. - requested_token_type
-
선택사항입니다. 이 매개 변수는 클라이언트가 교환하려는 토큰 유형을 나타냅니다. 현재 oauth 및 OpenID Connect 토큰 유형만 지원됩니다. 이 기본값은 응답 내에서 액세스 토큰과 새로 고침 토큰을 모두 반환하는 경우
urn:ietf:params:oauth:token-type:refresh_token
인지 여부에 따라 달라집니다. 기타 적절한 값은urn:ietf:params:oauth:token-type:access_token
및urn:ietf:params:oauth:token-type:id_token
입니다. - 대상
- 선택사항입니다. 이 매개변수는 새 토큰이 Mint된 대상 클라이언트를 지정합니다.
- requested_issuer
-
선택사항입니다. 이 매개변수는 클라이언트가 외부 공급자가 Mint된 토큰을 가져오도록 지정합니다. 영역 내에 구성된
ID 공급자
의 별칭이어야 합니다. - requested_subject
- 선택사항입니다. 클라이언트가 다른 사용자로 가장하려는 경우 사용자 이름 또는 사용자 ID를 지정합니다.
- scope
- 구현되지 않습니다. 이 매개변수는 클라이언트가 요청하는 OAuth 및 OpenID Connect 범위의 대상 세트를 나타냅니다. 현재 구현되지 않지만 Red Hat Single Sign-On이 일반적으로 범위를 더 잘 지원하게 되면 됩니다.
현재 OpenID Connect 및 OAuth 교환만 지원합니다. 사용자 요구에 따라 SAML 기반 클라이언트 및 ID 공급자에 대한 지원이 향후 추가될 수 있습니다.
7.1.2. 토큰 교환 요청의 응답
교환 호출에서 성공한 응답에서는 클라이언트가 요청하는 requested-token-type
및 requested_issuer
에 따라 달라지는 콘텐츠 유형이 포함된 HTTP 200 응답 코드를 반환합니다. OAuth 요청된 토큰 유형은 OAuth 토큰 교환 사양에 설명된 대로 JSON 문서를 반환합니다.
{ "access_token" : ".....", "refresh_token" : ".....", "expires_in" : "...." }
{
"access_token" : ".....",
"refresh_token" : ".....",
"expires_in" : "...."
}
새로 고침 토큰을 요청하는 클라이언트는 응답에서 액세스 및 새로 고침 토큰을 모두 반환합니다. 액세스 토큰 유형만 요청하는 클라이언트는 응답에서 액세스 토큰만 가져옵니다. 만료 정보는 requested_issuer
paramater를 통해 외부 발행자를 요청하는 클라이언트에 포함되거나 포함되지 않을 수 있습니다.
오류 응답은 일반적으로 400 HTTP 응답 코드 범주에 속하지만 오류 심각도에 따라 다른 오류 상태 코드가 반환될 수 있습니다. 오류 응답에는 requested_issuer
에 따라 내용이 포함될 수 있습니다. OAuth 기반 교환은 다음과 같이 JSON 문서를 반환할 수 있습니다.
{ "error" : "...." "error_description" : "...." }
{
"error" : "...."
"error_description" : "...."
}
추가 오류 클레임은 교환 유형에 따라 반환될 수 있습니다. 예를 들어, OAuth ID 공급자는 사용자에게 ID 공급자에 대한 링크가 없는 경우 추가 account-link-url
클레임을 포함할 수 있습니다. 이 링크는 클라이언트 시작 링크 요청에 사용할 수 있습니다.
토큰 교환 설정에는 세분화된 관리자 권한에 대한 지식이 필요합니다(자세한 내용은 서버 관리 가이드 참조). 교환할 수 있는 권한을 고객에게 부여해야 합니다. 이 내용은 이 장의 뒷부분에서 자세히 설명합니다.
이 장의 나머지 부분에서는 설정 요구 사항에 대해 설명하고 다양한 교환 시나리오에 대한 예를 제공합니다. 단순화를 위해 현재 영역에 의해 축소된 토큰을 내부 토큰으로 호출하고 외부 영역 또는 ID 공급자에 의해 외부 토큰으로 Mint되는 토큰을 호출합니다.
7.2. 내부 토큰 교환에 대한 내부 토큰
토큰 교환에 내부 토큰을 사용하면 특정 클라이언트에 기존 토큰이 Mint되어 다른 대상 클라이언트에 대해 새 토큰을 교환해야 합니다. 이 작업을 수행하는 이유는 무엇입니까? 일반적으로 클라이언트는 자체적으로 Mint된 토큰이 있고 액세스 토큰 내에서 다른 클레임 및 권한이 필요한 다른 애플리케이션에 추가 요청을 해야 하는 경우 +가 발생합니다. 이러한 유형의 교환이 필요할 수 있는 다른 이유는 앱이 덜 신뢰할 수 있는 앱에서 호출해야 하며 현재 액세스 토큰을 전파하지 않는 "권한 다운그레이드"를 수행해야 하는 경우입니다.
7.2.1. 교환에 대한 권한 부여
다른 클라이언트의 토큰을 교환하려는 클라이언트는 Admin Console에서 승인해야 합니다. 교환 권한을 원하는 대상 클라이언트에서 token-exchange
의 미세한 계량 권한을 정의해야 합니다.
대상 클라이언트 권한
절차
사용 권한 활성화를 ON 으로 전환합니다.
대상 클라이언트 권한
해당 페이지에는 token-exchange 링크가 표시됩니다.
해당 링크를 클릭하여 권한 정의를 시작합니다.
이 설정 페이지가 표시됩니다.
대상 클라이언트 교환 권한 설정
- Authorization 링크를 클릭하여 이 권한에 대한 정책을 정의
- 정책 탭을 클릭합니다.
클라이언트 정책을 생성합니다.
클라이언트 정책 생성
- 토큰 교환을 요청하는 인증된 클라이언트인 시작 클라이언트에 입력합니다.
이 정책을 생성한 후 대상 클라이언트의 token-exchange 권한으로 돌아가서 방금 정의한 클라이언트 정책을 추가합니다.
클라이언트 정책 적용
이제 클라이언트에서 호출할 수 있는 권한이 있습니다. 이 작업을 올바르게 수행하지 않으면 교환을 시도하면 403 Forbidden 응답이 표시됩니다.
7.2.2. 요청하기
클라이언트가 다른 클라이언트를 대상으로 하는 토큰의 기존 토큰을 교환하는 경우 audience
매개변수를 사용합니다. 이 매개변수는 Admin Console에서 구성한 대상 클라이언트의 클라이언트 식별자여야 합니다.
curl -X POST \ -d "client_id=starting-client" \ -d "client_secret=the client secret" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "subject_token=...." \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:refresh_token" \ -d "audience=target-client" \ http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:refresh_token" \
-d "audience=target-client" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
subject_token
매개변수는 대상 영역의 액세스 토큰이어야 합니다. requested_token_type
매개변수가 새로 고침 토큰 유형인 경우 응답에 액세스 토큰, 새로 고침 토큰 및 만료가 모두 포함됩니다. 다음은 이 호출에서 반환하는 JSON 응답의 예입니다.
audience
매개변수가 설정되지 않은 경우 매개변수 값은 기본적으로 클라이언트에서 토큰 교환 요청을 수행합니다.
기밀 클라이언트와 달리 공용 클라이언트는 다른 클라이언트의 토큰을 사용하여 토큰 교환을 수행할 수 없습니다. subject_token
을 통과하는 경우 토큰을 발행한 (기밀한) 클라이언트가 요청을 수행하는 클라이언트와 일치하거나 다른 클라이언트에 발행되는 경우 요청을 수행하는 클라이언트는 토큰으로 설정된 대상자 중 하나여야 합니다.
대상 대상을 명시적으로 설정하는 경우(클라이언트와 요청이 다른 경우), 클라이언트가 교환을 성공적으로 완료하기 위해 클라이언트가 요청을 수락하도록 클라이언트가
매개변수로 설정할 수 있도록 audience
token-exchange
범위 권한이 구성되어 있는지 확인해야 합니다.
{ "access_token" : "....", "refresh_token" : "....", "expires_in" : 3600 }
{
"access_token" : "....",
"refresh_token" : "....",
"expires_in" : 3600
}
7.3. 외부 토큰 교환에 대한 내부 토큰
외부 ID 공급자에 의해 Mint된 외부 토큰의 영역 토큰을 교환할 수 있습니다. 이 외부 ID 공급자는 관리 콘솔의 ID 공급자
섹션에서 구성해야 합니다. 현재 OAuth/OpenID Connect 기반 외부 ID 공급자만 지원되며 여기에는 모든 소셜 공급자가 포함됩니다. Red Hat Single Sign-On은 외부 공급자에게 백채널 교환을 수행하지 않습니다. 따라서 계정이 연결되지 않으면 외부 토큰을 가져올 수 없습니다. 이러한 조건 중 하나를 충족하려면 외부 토큰을 충족해야 합니다.
- 사용자가 외부 ID 공급자를 한 번 이상 로그인해야 합니다.
- 사용자는 사용자 계정 서비스를 통해 외부 ID 공급자와 연결되어 있어야 합니다.
- 사용자 계정은 Client Initiated Account Linking API를 사용하여 외부 ID 공급자를 통해 연결됩니다.
마지막으로, 외부 ID 공급자가 토큰을 저장하도록 구성되었거나 위의 작업 중 하나를 교환하는 내부 토큰과 동일한 사용자 세션을 사용하여 수행해야 합니다.
계정이 연결되지 않은 경우 교환 응답에는 이를 설정하는 데 사용할 수 있는 링크가 포함됩니다. 이 내용은 요청 구성 섹션에서 자세히 설명합니다.
7.3.1. 교환에 대한 권한 부여
외부 토큰 교환 요청 내부에서는 호출 클라이언트가 외부 ID 공급자와 토큰을 교환할 수 있는 권한을 부여할 때까지 403, Forbidden 응답이 거부됩니다. 클라이언트에 권한을 부여하려면 ID 공급자의 구성 페이지로 이동하여 권한 탭으로 이동합니다.
ID 공급자 권한
절차
사용 권한 활성화를 ON 으로 전환합니다.
ID 공급자 권한
페이지에 token-exchange 링크가 표시됩니다.
링크를 클릭하여 권한 정의를 시작합니다.
설정 페이지가 나타납니다.
ID 공급자 교환 권한 설정
Authorization 링크를 클릭하고 Policies 탭으로 이동하여 클라이언트 정책을 생성합니다.
클라이언트 정책 생성
- 토큰 교환을 요청하는 인증된 클라이언트인 시작 클라이언트를 입력합니다.
ID 공급자의 token-exchange 권한으로 돌아가 방금 정의한 클라이언트 정책을 추가합니다.
클라이언트 정책 적용
이제 클라이언트에서 호출할 수 있는 권한이 있습니다. 이 작업을 올바르게 수행하지 않으면 교환을 시도하면 403 Forbidden 응답이 표시됩니다.
7.3.2. 요청하기
클라이언트가 기존 내부 토큰을 외부 토큰으로 교환하는 경우 requested_issuer
매개변수를 제공합니다. 매개변수는 구성된 ID 공급자의 별칭이어야 합니다.
curl -X POST \ -d "client_id=starting-client" \ -d "client_secret=the client secret" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "subject_token=...." \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \ -d "requested_issuer=google" \ http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "requested_issuer=google" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
subject_token
매개변수는 대상 영역의 액세스 토큰이어야 합니다. requested_token_type
매개변수는 urn:ietf:params:oauth:token-type:access_token
또는 비어 있어야 합니다. 현재 요청한 다른 토큰 유형은 지원되지 않습니다. 이 호출에서 반환된 JSON 응답의 예는 다음과 같습니다.
{ "access_token" : "....", "expires_in" : 3600 "account-link-url" : "https://...." }
{
"access_token" : "....",
"expires_in" : 3600
"account-link-url" : "https://...."
}
어떤 이유로 외부 ID 공급자가 연결되지 않은 경우 다음 JSON 문서와 함께 HTTP 400 응답 코드를 받습니다.
{ "error" : "....", "error_description" : "..." "account-link-url" : "https://...." }
{
"error" : "....",
"error_description" : "..."
"account-link-url" : "https://...."
}
오류
클레임은 token_expired
또는 not_linked
입니다. 클라이언트가 클라이언트 시작 계정 연결을 수행할 수 있도록 account-link-url
클레임이 제공됩니다. 대부분의 공급업체는 브라우저 OAuth 프로토콜을 통해 연결해야 합니다. account-link-url
을 사용하여 redirect_uri
쿼리 매개변수를 추가하고 브라우저를 전달하여 링크를 수행할 수 있습니다.
7.4. 내부 토큰 교환에 대한 외부 토큰
외부 ID 공급자가 내부 토큰을 신뢰하고 교환할 수 있습니다. 이 방법은 영역을 연결하거나 소셜 공급자의 토큰을 신뢰하는 데 사용할 수 있습니다. 이 기능은 존재하지 않는 경우 새 사용자가 해당 영역으로 가져온 ID 공급자 브라우저 로그인과 유사하게 작동합니다.
외부 토큰 교환에 대한 현재 제한은 외부 토큰이 기존 사용자에게 기존 사용자에게 매핑되는 경우 기존 사용자에게 이미 외부 ID 공급자에 대한 계정 링크가 없는 경우 허용되지 않는다는 것입니다.
교환이 완료되면 사용자 세션이 영역 내에 생성되고 requested_token_type
매개변수 값에 따라 액세스 및 또는 새로 고침 토큰이 부여됩니다. 이 새 사용자 세션은 시간 초과되거나 이 새 액세스 토큰을 통과하는 영역의 로그 아웃 끝점을 호출할 때까지 활성 상태로 유지됩니다.
이러한 유형의 변경에는 Admin Console에 구성된 ID 공급자가 필요합니다.
현재 SAML ID 공급자는 지원되지 않습니다. 또한 twitter 토큰을 교환할 수 없습니다.
7.4.1. 교환에 대한 권한 부여
외부 토큰 교환을 수행하기 전에 호출 클라이언트가 교환할 수 있는 권한을 부여합니다. 이 권한은 내부 외부 권한과 동일한 방식으로 부여됩니다.
호출 대상이 아닌 다른 클라이언트를 가리키는 audience
매개 변수도 제공하는 경우 호출 클라이언트 권한을 audience
매개 변수의 특정 대상 클라이언트로 교환할 수도 있어야 합니다. 이 작업을 수행하는 방법은 이 섹션의 앞부분에서 설명합니다.
7.4.2. 요청하기
subject_token_type
은 urn:ietf:params:oauth:token-type:access_token
또는 urn:ietf:params:oauth:token-type:jwt
여야 합니다. 유형이 urn:ietf:params:oauth:token-type:access_token
_token인 경우 subject_issuer
매개변수를 지정하고 구성된 ID 공급자의 별칭이어야 합니다. 유형이 urn:ietf:params:oauth:token-type:jwt
인 경우 공급자는 JWT 내의 발행자
클레임을 통해 일치하며, 공급자 구성 내의 등록된 발급자 또는 공급자 구성 내의 등록된 발급자입니다.
검증을 위해 토큰이 액세스 토큰인 경우 공급자의 사용자 정보 서비스가 호출되어 토큰을 검증합니다. 호출에 성공하면 액세스 토큰이 유효합니다. 주체 토큰이 JWT이고 공급자의 서명 유효성 검사가 활성화된 경우, 그러지 않으면 기본적으로 사용자 정보 서비스에서 를 호출하여 토큰을 검증합니다.
기본적으로 minted 내부 토큰을 사용하여 호출 클라이언트에 정의된 프로토콜 매퍼를 사용하여 토큰에 있는 항목을 확인합니다. 또는 audience
매개변수를 사용하여 다른 대상 클라이언트를 지정할 수 있습니다.
curl -X POST \ -d "client_id=starting-client" \ -d "client_secret=the client secret" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "subject_token=...." \ -d "subject_issuer=myOidcProvider" \ --data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \ -d "audience=target-client" \ http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=...." \
-d "subject_issuer=myOidcProvider" \
--data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=target-client" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
requested_token_type
매개변수가 새로 고침 토큰 유형인 경우 응답에 액세스 토큰, 새로 고침 토큰 및 만료가 모두 포함됩니다. 다음은 이 호출에서 반환하는 JSON 응답의 예입니다.
{ "access_token" : "....", "refresh_token" : "....", "expires_in" : 3600 }
{
"access_token" : "....",
"refresh_token" : "....",
"expires_in" : 3600
}
7.5. 가장
내부 및 외부 토큰 교환의 경우 클라이언트는 사용자를 대신하여 다른 사용자로 가장하도록 요청할 수 있습니다. 예를 들어 지원 엔지니어가 문제를 디버깅할 수 있도록 사용자를 가장해야 하는 admin 애플리케이션이 있을 수 있습니다.
7.5.1. 교환에 대한 권한 부여
주체 토큰이 나타내는 사용자는 다른 사용자로 가장할 수 있는 권한이 있어야 합니다. 이 권한을 활성화하는 방법에 대한 서버 관리 가이드를 참조하십시오. 이는 역할을 통해 또는 미세 조정된 관리자 권한을 통해 수행할 수 있습니다.
7.5.2. 요청하기
requested_subject
매개변수를 추가로 지정하는 경우를 제외하고 다른 장에서 설명한 대로 요청을 만듭니다. 이 매개변수의 값은 사용자 이름 또는 사용자 ID여야 합니다.
curl -X POST \ -d "client_id=starting-client" \ -d "client_secret=the client secret" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "subject_token=...." \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \ -d "audience=target-client" \ -d "requested_subject=wburke" \ http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=target-client" \
-d "requested_subject=wburke" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
7.6. 바로 Naked Impersonation
subject_token
을 제공하지 않고 내부 토큰 교환 요청을 할 수 있습니다. 이는 클라이언트가 영역에 모든 사용자를 가장할 수 있으므로 클라이언트에 많은 신뢰를 배치하기 때문에 직접 naked impersonation이라고 합니다. 이를 교환할 대상 토큰을 얻을 수 없는 애플리케이션을 브릿지해야 할 수 있습니다. 예를 들어 LDAP와 직접 로그인을 수행하는 레거시 애플리케이션을 통합할 수 있습니다. 이 경우 레거시 앱은 사용자 자체를 인증할 수 있지만 토큰을 가져올 수 없습니다.
고객에게 직접 육아 가장을 사용하는 것은 매우 위험합니다. 클라이언트의 자격 증명이 손상되면 해당 클라이언트는 시스템의 모든 사용자를 가장할 수 있습니다.
7.6.1. 교환에 대한 권한 부여
audience
매개 변수가 제공되면 호출 클라이언트에 클라이언트로 교환할 수 있는 권한이 있어야 합니다. 이 장의 앞부분에서 이 설정을 설정하는 방법에 대해 설명합니다.
또한 호출 클라이언트에는 사용자를 가장할 수 있는 권한이 부여되어야 합니다. 관리 콘솔에서 다음을 수행합니다.
절차
- 메뉴에서 사용자를 클릭합니다.
권한 탭을 클릭합니다.
사용자 권한
사용 권한을 true 로 전환합니다.
ID 공급자 권한
페이지에는 가장 링크가 표시됩니다.
해당 링크를 클릭하여 권한 정의를 시작합니다.
이 설정 페이지가 표시됩니다.
사용자 Impersonation 권한 설정
- Authorization 링크를 클릭합니다.
Policies 탭으로 이동하여 클라이언트 정책을 생성합니다.
클라이언트 정책 생성
- 토큰 교환을 요청하는 인증된 클라이언트인 시작 클라이언트를 입력합니다.
사용자의 가장 권한으로 돌아가 방금 정의한 클라이언트 정책을 추가합니다.
클라이언트 정책 적용
이제 클라이언트는 사용자를 가장할 수 있는 권한이 있습니다. 이 작업을 올바르게 수행하지 않으면 이러한 유형의 교환을 시도하면 403 Forbidden 응답이 표시됩니다.
공개 클라이언트는 직접 육안을 할 수 없습니다.
7.6.2. 요청하기
요청하려면 requested_subject
매개변수를 지정하기만 하면 됩니다. 유효한 사용자의 사용자 이름 또는 사용자 ID여야 합니다. 원하는 경우 audience
매개변수를 지정할 수도 있습니다.
curl -X POST \ -d "client_id=starting-client" \ -d "client_secret=the client secret" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "requested_subject=wburke" \ http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "requested_subject=wburke" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
7.7. 서비스 계정을 사용하여 권한 모델 확장
고객에게 교환에 대한 권한을 부여할 때 각 클라이언트에 대해 이러한 권한을 수동으로 활성화할 필요는 없습니다. 클라이언트에 연결된 서비스 계정이 있는 경우 역할을 사용하여 권한을 그룹화하고 클라이언트의 서비스 계정에 역할을 할당하여 교환 권한을 할당할 수 있습니다. 예를 들어 naked-exchange
역할 및 해당 역할이 있는 서비스 계정을 정의할 수 있습니다.
7.8. 취약점 교환
토큰 교환을 허용하기 시작할 때, 둘 다 알고 주의해야 할 여러 가지가 있습니다.
첫 번째는 공개 고객입니다. 공용 클라이언트에는 교환을 수행하기 위해 클라이언트 자격 증명이 없거나 필요하지 않습니다. 유효한 토큰이 있는 everyone은 공개 클라이언트를 가장 하고 공용 클라이언트가 수행할 수 있는 공지를 수행할 수 있습니다. 해당 영역에 의해 관리되는 신뢰할 수 없는 클라이언트가 있는 경우 공용 클라이언트는 권한 모델의 취약점을 열 수 있습니다. 이를 위해 직접 육안 거래에서 공용 클라이언트를 허용하지 않으며 호출 클라이언트가 공용인 경우 오류로 중단됩니다.
영역 토큰으로 Facebook, Google 등에서 제공하는 소셜 토큰을 교환할 수 있습니다. 이러한 소셜 웹 사이트에서 위조 계정을 생성하기 어렵지 않기 때문에 교환 토큰이 허용되는 작업에 주의하고 vigilante하십시오. 기본 역할, 그룹 및 ID 공급자 매퍼를 사용하여 외부 소셜 사용자에게 할당되는 속성 및 역할을 제어합니다.
직접 육상권은 매우 위험할 수 있습니다. 클라이언트 자격 증명이 유출되지 않을 것이라는 호출 클라이언트에 많은 신뢰를 제공하고 있습니다. 해당 자격 증명이 유출되면 도장에서 시스템에서 다른 자격 증명을 가장할 수 있습니다. 이는 기존 토큰이 있는 기밀 고객과 직접적인 대조적입니다. 인증의 두 가지 요인인 액세스 토큰과 클라이언트 자격 증명은 하나의 사용자만 다룹니다. 따라서 직접 육식 절개를 사용하십시오.