記事「XSUAAでOAuth2.0認証のREST API作成(SAP Cloud SDK for Java使用) リソースオーナーパスワード使用」の
Client Credentials Flow編です。A2AのためのREST APIであれば技術ユーザの認証をするこっちの方が向いています。
時間を大きく割けないので簡潔に書きます。
開発環境
以下の環境で実行しています。
- OS: Windows10 64-bit
- openJDK: 1.8.0_262
- Chocolatey: 0.10.15
- maven: 3.6.3
- IDE: IntelliJ IDEA Community Edition 2019.3.3
- CF cli: 6.51.0+2acd15650.2020-04-07
- SAP Cloud SDK for Java: 3.26.0
手順
1. Java プロジェクト作成
まずは、コマンドプロンプトからmavenでプロジェクト作成。
mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"
途中のプロンプトでは以下を入力。”artifactId”に入力した”api-oauth”がApplication名です。
- groupId: com.sap.cloud.sdk.oauth
- artifactId: api-oauth
- version: 1.0-SNAPSHOT
- package: com.sap.cloud.sdk.oauth
2. XSUAAサービス作成
まずは準備です。
プロジェクトルート直下にファイル”.cfignore”を作成。定義したファイル/フォルダがCFへデプロイするときに無視されます(.gitignore感覚)。
# exclude xsuaa folder
/xsuaa
で、プロジェクトルート直下にディレクトリ”xsuaa”を作成し、そこにファイル”xs-security.json”を作成。技術ユーザが認証するので、ロールなどは不要です。
{
"xsappname": "api-oauth",
"tenant-mode": "dedicated"
}
カレントディレクトリを”xsuaa”にしてcf cliでxsuaaサービスを作成。
cf create-service xsuaa application my-xsuaa -c xs-security.json
3. Java開発
Servletのソースです。デフォルトで作成されるHelloWorldServletを変更しています。
package com.sap.cloud.sdk.oauth;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.sap.cloud.sdk.cloudplatform.security.AuthToken;
import com.sap.cloud.sdk.cloudplatform.security.exception.AuthTokenAccessException;
import static com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.getCurrentToken;
@WebServlet("/hello")
public class HelloWorldServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws IOException {
try {
AuthToken authToken = getCurrentToken();
response.getWriter().append(authToken.toString());
} catch (AuthTokenAccessException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
}
}
}
“application/src/main/webapp/WEB-INF/web.xml”の変更は不要みたいです。
プロジェクト全体をビルドします。
# from project root directory
mvn clean install
4. CFへデプロイ
manifest.ymlを変更します。サービスにXSUAAを紐付けしています。
---
applications:
- name: api-oauth
memory: 1024M
timeout: 300
routers:
- route: https://<適当にホスト名を指定>.cfapps.us10.hana.ondemand.com
path: application/target/api-oauth-application.war
buildpacks:
- sap_java_buildpack
env:
TARGET_RUNTIME: tomee7
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'
JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..'
services:
- my-xsuaa
cliでデプロイします。
cf push
結果とAPIアクセス
これでブラウザからJavaアプリケーションにアクセスしようとしても401(Unauthorized)となります。
POSTMANからTokenを取得して、APIにアクセスしてみます。
XSUAA情報取得
まずはSAP Cloud CockpitからXSUAAの情報を取得します。
作成したXSUAAのReferencing Appsを開きます。以降で使うのはclientid, clientsecretとurlです。
※cf cliでも"cf env <app name>"で取得できるようです(bindされていれば)。
Token取得
まずは認証サーバからTokenを取得します。Bodyの値のタイプがx-www-form-urlencodedであることに注意します。
項目 |
設定値 |
エンドポイント |
XSUAAの”url”の値 + /oauth/token |
HTTP メソッド |
POST |
BodyのKey Value(grant_type) |
固定値”client_credentials” |
BodyのKey Value(client_id) |
XSUAAの”clientid”の値 |
BodyのKey Value(client_secret) |
XSUAAの”clientsecret”の値 |
BodyのKey Value(response_type) |
固定値”token” |
API呼出
取得したTokenを使ってAPIを呼び出します。呼出先はJavaのアプリケーションのエンドポイントにパスとして”/hello”をつけています。
HTTP HeaderのKeyを”Authorization”にしてValueに”Bearer”と取得したToken(responseの”access_token”の値)を半角スペース区切りで結合してセットします。
“com.sap.cloud.sdk.cloudplatform.security.AuthToken@7970a55e”のようなToken情報が返ってきて成功です。