OpenShiftのOAuthサーバーを認証プロバイダーとして使用して、Libertyへのアクセスを認証する方法


はじめに

当記事では、OpenShiftのOAuthサーバーを認証プロバイダとして使用して、コンテナ上のLibertyを認証する方法を記述します。
環境はOpenShift4.6です。
前提として、ある程度JakartaEE/J2EE 等の知識があることを想定しています。

以下の2パターンのうち、1のパターンについて記述します。
この方法は、2に至る前のテスト接続の確認としても有用です。

  1. OAuthのための設定値を静的に設定する
  2. オペレータからアプリケーションをデプロイし、オペレータからサービスアカウントの作成、および、設定値を動的に設定する。

LibertyからOpenShift上のOAuthサーバーを使用する方法は、以下の記事を参考にしています。

サービスアカウントをOauthクライアントとして使用する方法は、以下の記事を参考にしています。

Oauthのための設定値を静的に設定する

Oauthのための設定値を静的に設定する方法は、アプリケーションが動作するOpenShiftのインスタンスが決まっている状況に有用です。

手順概要

Oauthのための設定値を静的に設定する手順の概要は、下記になります。

  1. アプリケーションを保護および、Basic Registryを使用した認証のテスト
  2. Service Accountの作成
  3. Service Accountにredirecturiの設定
  4. Service AccountにClusterRoleおよびClusterRoleBindingを設定
  5. Service Accountのトークンを取得
  6. Libertyのserver.xmlに、oauth2loginを設定
  7. APIサーバーの証明書をLibertyが使用するJVMのtruststoreにインポート

1 アプリケーションを保護および、Basic Registryを使用した認証のテスト

まずは、アプリケーションの保護、および、Basic Registryを使用した認証をテストします。

詳細の説明は省きますが、
Webアプリケーションで使用するweb.xmlやLibertyで使用するserver.xmlに、アプリケーションの保護設定および認証設定を行い、稼働をテストします。

この設定により、Libertyで稼働するWebアプリケーションのリソースにアクセスした際に、認証を求められます。
その認証時には、Basic Registryで指定したユーザーおよび、パスワードによって、認証することができます。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="DownloadApps" version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">

 <!-- SECURITY ROLES -->
 <security-role>
    <role-name>downloader</role-name>
 </security-role>

 <!-- SECURITY CONSTRAINTS -->
 <security-constraint>
    <web-resource-collection>
      <web-resource-name>all</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>downloader</role-name>
    </auth-constraint>
 </security-constraint>

 <!-- AUTHENTICATION METHOD: Basic authentication -->
 <login-config>
    <auth-method>BASIC</auth-method>
 </login-config> 

 <display-name>DownloadApps</display-name>
</web-app>
server.xml
    <webApplication location="DownloadApps.war" contextRoot="/">
            <application-bnd>
            <security-role name="downloader">
                <special-subject type="ALL_AUTHENTICATED_USERS" />
                <group name="admin"/>
            </security-role>
        </application-bnd>
    </webApplication>
    <basicRegistry>
        <user password="secret" name="test"></user>
        <group name="admin">
            <member name="test"></member>
        </group>
    </basicRegistry>

2 Service Accountの作成

OAuth認証をするためのOAuth ClientにOpenShift上のService Accountを使用します。
そのServcie AccountをOpenShiftで作成します。

kind: ServiceAccount
apiVersion: v1
metadata:
  name: sample-sa
  namespace: default

画面例

3 Service AccountのAnnotationsにredirecturiの設定

Servcie AccountのAnnotationsに、LibertyのSocial Login用のリダイレクトURIを指定します。

key value
serviceaccounts.openshift.io/oauth-redirecturi.first https://xxxx:9443/ibm/api/social-login/redirect/openshiftLogin

FQDNのxxxの部分は、環境に応じて指定してください。

画面例

4 Service AccountにClusterRoleおよびClusterRoleBindingを設定

tokenreviewsとsubjectaccessreviewsをcreateできるClusterRoleを作成します。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: auth-tokenreviews
rules:
  - verbs:
      - create
    apiGroups:
      - authentication.k8s.io
    resources:
      - tokenreviews
      - subjectaccessreviews

Cluster Role Bindingを作成し、Cluster RoleとService AccountをBindします。

5 サービスアカウントのトークンを取得

作成したサービスアカウントのトークンを取得します。
このトークンを、libertyのserver.xmlのoauth2Login のclientSecretとuserApiTokenに設定します。

oc sa get-token <service_account_name>

6 Libertyのserver.xmlに、oauth2loginを設定

ibertyのserver.xmlに、oauth2loginを設定します。

server.xml
    <variable name="serviceAccountName" defaultValue="system:serviceaccount:<namespace>:<serviceaccount>"  />
    <variable name="token" defaultValue="XXXXXX"/>
    <variable name="authEndpointUrl" defaultValue="https://oauth-openshift.apps.<FQDN>/oauth/authorize"  />
    <variable name="tokenEndpointUrl" defaultValue="https://oauth-openshift.apps.<FQDN>/oauth/token"  />
    <variable name="userApiUrl" defaultValue="https://api.<FQDN>:6443/apis/authentication.k8s.io/v1/tokenreviews"  />
    <oauth2Login id="openshiftLogin"
      scope="user:info"
      clientId="system:serviceaccount:default:${serviceAccountName}"
      clientSecret="${token}"
      authorizationEndpoint="${authEndpointUrl}"
      tokenEndpoint="${tokenEndpointUrl}"
      userNameAttribute="username"
      groupNameAttribute="groups"
      userApiToken="${token}"
      userApiType="kube"
      userApi="${userApiUrl}">
  </oauth2Login>
server.xml
    <webApplication location="DownloadApps.war" contextRoot="/">
        <application-bnd>
            <security-role name="downloader">
                <special-subject type="ALL_AUTHENTICATED_USERS" />
            </security-role>
        </application-bnd>
    </webApplication>

7 APIサーバーの証明書をLibertyが使用するJVMのtruststoreにインポート

OpenShiftのAPIサーバーの証明書を、Libertyが使用するJVMのtruststoreにインポートしないと、
LibertyからOpenShiftのAPIサーバーにアクセスしたときにSSL Handshakeのエラーが発生します。

エラーの例
[ERROR   ] CWPKI0823E: SSL HANDSHAKE FAILURE:  A signer with SubjectDN [CN=*.apps.xxx.com] was sent from the host [oauth-openshift.apps.xxx.com:443].  The signer might need to be added to local trust store [/opt/ol/wlp/output/defaultServer/resources/security/key.p12], located in SSL configuration alias [defaultSSLConfig].  The extended error message from the SSL handshake exception is: [PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target].
[ERROR   ] CWPKI0828E: The trustDefaultCerts attribute is enabled but trust was not established by using the default truststore. The extended error message from the SSL handshake exception is: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
[ERROR   ] CWWKS5451E: The social login feature encountered a problem while obtaining token information from the token endpoint that is configured for the social login configuration [openshiftLogin]. CWWKS5476E: An error occurred while making a request to the provided URL [https://oauth-openshift.xxx.com/oauth/token]. PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

APIサーバーの証明書をLibertyが使用するJVMのtruststoreにインポートする方法

OpenShiftのコンソールにアクセスし、ブラウザを使用して証明書をダウンロードします。

Firefoxの場合、ブラウザのURL横の鍵アイコンを押下し、証明書を表示し、ダウンロードします。

PEM(CERT)というリンクから、証明書をダウンロードできます。

keytool.exe -list -keystore C:/DownloadApps/target/liberty/wlp/usr/servers/defaultServer/resources/security/key.p12 -storepass XXXX
keytool.exe -importcert -keystore C:/DownloadApps/target/liberty/wlp/usr/servers/defaultServer/resources/security/key.p12 -storepass xxxx -file "C:\Downloads\apps-xxx-com.pem

同様に、LibertyのuserApiに指定する下記のようなページにアクセスし、同様に証明書のダウンロードとインポートを行います。
https://api.xxxx.com:6443/apis/authentication.k8s.io/v1/tokenreviews

この証明書のインポートの部分は、もしかすると、もう少しスマートな方法があるかもしれません。

期待の動き

  1. Libertyの任意のアプリケーションURLにアクセスします
  2. OpenShiftの認証ページにリダイレクトされます。
  3. OpenShiftのクレデンシャルでログインします。
  4. LibertyのアプリケーションURLにダイレクトされます。

OpenShiftの認証ページ

まとめ

この記事では、OAuthのための設定値を静的に設定し、OpenShiftのOAuthサーバーを認証プロバイダとして使用して、Libertyを認証する方法を記しました。

誰かの助けになれば、幸いです。