Keycloakの統合–SwaggerUIを使用したOAuth2とOpenID
1. 概要
このチュートリアルでは、保護され、SwaggerUIを使用した認証と承認にKeycloakを使用するRESTサービスをテストする方法に焦点を当てます。
2. チャレンジ
他のWebリソースと同様に、RESTAPIは多くの場合保護されています。 したがって、サービスコンシューマー(Swagger UIなど)は、HTTP呼び出し自体を処理するだけでなく、サービスプロバイダーに認証情報を提供する必要があります。
Keycloakは、サービスプロバイダーの実装の外部で認証と承認を可能にするIAMサーバーです。 次の図に示すように、これはアーキテクチャの一部です。
ご覧のとおり、サービスプロバイダーとサービスコンシューマーの両方がKeycloakサーバーに接続する必要があります。 まず、 Keycloakサーバーをインストールし、RESTサービスプロバイダーとしてSpring Bootアプリケーションに統合する必要があります。 次に、SwaggerUIを拡張する必要があります。
3. SwaggerUIのカスタマイズ
このようなスクリプトをHTMLに含めることで、SwaggerUIを直接拡張できます。
<script src="keycloak/keycloak.js"></script>
<script>
var keycloak = Keycloak('keycloak.json');
keycloak.init({ onLoad: 'login-required' })
.success(function (authenticated) {
console.log('Login Successful');
window.authorizations.add("oauth2", new ApiKeyAuthorization("Authorization", "Bearer " + keycloak.token, "header"));
}).error(function () {
console.error('Login Failed');
window.location.reload();
}
);
</script>
スクリプトはNPMパッケージとして利用できるため、 Swagger UIソースコードリポジトリをフォークし、対応する依存関係によってプロジェクトを拡張することができます。
4. 標準の使用
ベンダー固有のコードでSwaggerUIを拡張することは、非常に特殊な場合にのみ意味があります。 したがって、ベンダーに依存しない標準を使用することをお勧めします。 次のセクションでは、これを実装する方法について説明します。
4.1. 既存の規格
まず、どの規格が存在するかを知る必要があります。 認証と承認には、OAuth2のようなプロトコルがあります。 SSOの場合、 OpenID Connect (OIDC)をOAuth2の拡張機能として使用できます。
REST APIを記述するための標準は、OpenAPIです。 この標準には、OAuth2やOIDCを含む複数のセキュリティスキームの定義が含まれています。
paths:
/api/v1/products:
get:
...
security:
- my_oAuth_security_schema:
- read_access
...
securitySchemes:
my_oAuth_security_schema:
type: oauth2
flows:
implicit:
authorizationUrl: https://api.example.com/oauth2/authorize
scopes:
read_access: read data
write_access: modify data
4.2. サービスプロバイダーを拡張する
コードファーストのアプローチでは、サービスプロバイダーはコードに基づいてOpenAPIドキュメントを生成できます。 したがって、セキュリティスキームもこの方法で提供する必要があります。 たとえば、SpringFoxを含むSpring Bootを使用すると、次のような構成クラスを記述できます。
@Configuration
public class OpenAPISecurityConfig {
@Autowired
void addSecurity(Docket docket) {
docket
.securitySchemes(of(authenticationScheme()))
.securityContexts(of(securityContext()));
}
private SecurityScheme authenticationScheme() {
return new OAuth2SchemeBuilder("implicit")
.name("my_oAuth_security_schema")
.authorizationUrl("https://api.example.com/oauth2/authorize")
.scopes(authorizationScopes())
.build();
}
private List<AuthorizationScope> authorizationScopes() {
return Arrays.asList(
new AuthorizationScope("read_access", "read data"),
new AuthorizationScope("write_access", "modify data")
);
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(readAccessAuth())
.operationSelector(operationContext ->
HttpMethod.GET.equals(operationContext.httpMethod())
)
.build();
}
private List<SecurityReference> readAccessAuth() {
AuthorizationScope[] authorizationScopes = new AuthorizationScope[] { authorizationScopes().get(0) };
return of(new SecurityReference("my_oAuth_security_schema", authorizationScopes));
}
}
もちろん、他のテクノロジーを使用すると、さまざまな実装につながります。 ただし、生成する必要のあるOpenAPIを常に認識しておく必要があります。
4.3. サービスコンシューマーを拡張する
Swagger UIは、デフォルトでOpenAPI認証スキームをサポートしています。カスタマイズする必要はありません。 次に、認証する可能性があります。
他のクライアントは異なるソリューションを持っているでしょう。 たとえば、Angularアプリケーション用の NPMモジュールがあり、OAuth2とOpenID Connect(OIDC)を簡単な方法で提供します。
4.4. SwaggerUIの制限
Swagger UIは、バージョン3.38.0以降のOpenID Connect Discoveryをサポートしています(バージョン3.14.8以降のSwagger Editor)。 残念ながら、現在のバージョン3.0.0のSpringFoxはSwaggerUI3.26.2をパッケージ化しています。 したがって、新しいバージョンのSwagger UIを含める場合は、SpringFoxがSpringFoxパッケージファイルをシャドウするのと同じディレクトリ構造を使用して、アプリケーションに直接含める必要があります。
SpringDoc 1.6.1は代わりにSwaggerUIをパッケージ化しませんが、 Swagger UI 4.1.3 への推移的な依存関係を宣言するため、SpringDocで問題は発生しません。
5. 結論
この記事では、KeycloakをIAMとして使用する場合に、SwaggerUIを使用してRESTサービスをテストする可能性を指摘しました。 最善の解決策は、OpenAPI、OAuth2、OpenIDConnectなどの標準を使用することです。これらはすべてツールでサポートされています。
いつものように、すべてのコードはGitHubで利用できます。