Java SDK

Java SDK

Javaを用いたAuthorization Codeフローのサンプルコードの説明をします。

  • サポートバージョン
    • Java SE 7, 8, 11
  • 動作確認環境(サンプルコードを実行するための環境)
    • Apache Tomcat 7 / JRE 7
    • Apache Tomcat 8 / JRE 8
    • Apache Tomcat 9 / JRE 11
  • SDK&サンプルコード

SDKを利用するためには以下のライブラリー(外部サイト)が必要です。

Gradle で導入する場合

dependencies {
    implementation 'javax.json:javax.json-api:1.0'
    implementation 'javax.servlet:servlet-api:2.5'
    implementation 'log4j:log4j:1.2.17'
    implementation 'org.apache.httpcomponents:httpclient:4.5.2'
    implementation 'org.glassfish:javax.json:1.0.4'
}

ライブラリーをインポートする

はじめに必要なライブラリーをインポートします。ダウンロードしたjarファイルのビルド・パスを設定してください。
次にYahoo! ID連携 Java SDKを任意の場所にダウンロードして解凍してください。以下のjarファイルにはYahoo! ID連携を利用するために必要なクラスが定義されています。インポートしてご利用ください。

jp.co.yahoo.yconnect

Authorizationエンドポイントにリクエストして同意画面を表示する

YConnectClientクラスにはAuthorization Codeフローで必要なメソッドがすべて実装されています。
YConnectClientクラスを使って同意画面を表示させます。

YConnectClientクラス

メソッド 説明
public YConnectClient()
コンストラクタです。
public void init(
    String clientId,
    String redirectUri,
    String state,
    String responseType,
    String display,
    String[] prompt,
    String[] scope,
    String nonce,
    Long maxAge,
    String plainCodeChallenge
)
各パラメーターを設定します。
public URI generateAuthorizationUri()
リクエストURIを生成します。

OAuth2ResponseTypeクラス

定義済み定数 説明
public static final String CODE 認可コードを取得するための定数です。

OIDCScopeクラス

定義フィールド値 説明
public static final String OPENID
ユーザー識別子を取得するための定数です。
public static final String PROFILE
姓名・生年・性別を取得するための定数です。
public static final String EMAIL
メールアドレスと確認済みフラグを取得するための定数です。
public static final String ADDRESS
ユーザー登録住所情報を取得するための定数です。

OIDCDisplayクラス

定義フィールド値 説明
public static final String DEFAULT
UserAgentに適した形でページを表示するための定数です。
public static final String PC
パソコン版のテンプレートを表示するための定数です。
public static final String SMART_PHONE
スマートフォン版のテンプレートを表示するための定数です。
public static final String POPUP
ポップアップ版のテンプレートを表示するための定数です。
public static final String NATIVE_APP
ネイティブアプリ版のテンプレートを表示するための定数です。

OIDCPromptクラス

定義フィールド値 説明
public static final String DEFAULT
ユーザーの認証、認可のための定数です。
public static final String NONE
同意画面非表示のための定数です。(必須の場合はエラーが返却されます)
public static final String CONSENT
ユーザーの再認可のための定数です。
public static final String LOGIN
ユーザーの再認証のための定数です。
public static final String SELECT_ACCOUNT
ユーザーのID切替のための定数です。

// アプリケーションID、シークレット
private final static String clientId = "YOUR_APPLICATION_ID";
private final static String clientSecret = "YOUR_SECRET";
 
// コールバックURL
// (アプリケーションID発行時に登録したURL)
private static final String redirectUri = "https://YOUR_CALLBACK_HOST/YConnectServlet/YConnectServlet";
 
// リクエストとコールバック間の検証用のランダムな文字列を指定してください
String state = "5Ye65oi744KKT0vjgafjgZnjgojjgIHlhYjovKnjg4M=";
// リプレイアタック対策のランダムな文字列を指定してください
String nonce = "SUTljqjjga8uLi7jgrrjg4Plj4vjgaDjgoc=";
// Code Verifierとしてトークン置き換え攻撃対策のランダムな文字列を指定してください
// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
String plainCodeChallenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM";
 
// YConnectインスタンス取得
YConnectClient yconnect = new YConnectClient();
 
// 各パラメーター初期化
String responseType = OAuth2ResponseType.CODE;
String display = OIDCDisplay.DEFAULT;
String[] prompt = { OIDCPrompt.DEFAULT };
String[] scope = { OIDCScope.OPENID, OIDCScope.PROFILE,
        OIDCScope.EMAIL, OIDCScope.ADDRESS };
 
// 各パラメーターを設定
yconnect.init(clientId, redirectUri, state, responseType, display, prompt, scope, nonce, maxAge, plainCodeChallenge);
URI uri = yconnect.generateAuthorizationUri();
 
// Authorizationエンドポイントにリダイレクト(同意画面を表示)
response.sendRedirect(uri.toString());

実際の開発の際にはstate、nonce, plainCodeChallengeは固定の文字列ではなく独自の仕様でランダムな文字列を生成してデータベースなどに保存してください。stateはAuthorizationエンドポイントからのコールバックURL受け取り時、nonceはIDトークンを復号時、plainCodeChallengeはTokenエンドポイントへのリクエスト時に必要です。

plainCodeChallengeはS256としてSDK内でCode Challengeに変換され、クエリパラメータに含まれます。

各パラメーター値の詳細についてはAuthorizationエンドポイントを参照してください。

コールバックURLを受け取り、認可コードを抽出する

同意後に返されるコールバックURLを受け取り、認可コードなどを抽出します。

YConnectExplicitクラス

メソッド 説明
public boolean hasAuthorizationCode(String query)
クエリパラメータから認可コードを抽出し有無を確認します。
public boolean hasAuthorizationCode(Uri uri)
クエリパラメータ含まれるUriから認可コードを抽出し有無を確認します。
public String getAuthorizationCode(String state)
リクエスト時とコールバック時のstateの値を検証し認可コードを取得します。

// コールバックURLから各パラメーターを抽出
if(yconnect.hasAuthorizationCode(query)) {
    // 認可コードを取得
    String code = yconnect.getAuthorizationCode(state);
}

getAuthorizationCodeメソッドでリクエスト時の値とレスポンスのstateの検証を内部で行っています。検証が正しい場合は、認可コードを返します。エラーレスポンスが返された場合は内部で例外処理を投げます。

Tokenエンドポイントにリクエストしてアクセストークンを取得する

取得した認可コードを用いてアクセストークン、リフレッシュトークンを取得します。

YConnectClientクラス

メソッド 説明
public void requestToken(
    String code,
    String clientId,
    String clientSecret,
    String redirectUri,
    String codeVerifier
)
Tokenエンドポイントにリクエストしアクセストークン、リフレッシュトークン、IDトークンを取得します。
public String getAccessToken()
アクセストークンを取得します。
public long getAccessTokenExpiration()
アクセストークンの有効期限を取得します。
public String getRefreshToken()
リフレッシュトークンを取得します。
public String getIdToken()
IDトークンの文字列を取得します。
// Tokenエンドポイントにリクエスト
yconnect.requestToken(code, clientId, clientSecret, redirectUri, plainCodeChallenge);
// アクセストークン、リフレッシュトークン、IDトークンを取得
String accessTokenString = yconnect.getAccessToken();
long expiration = yconnect.getAccessTokenExpiration();
String refreshToken = yconnect.getRefreshToken();
String idTokenString = yconnect.getIdToken();

IDトークンを復号、検証してユーザー識別子を取得する

IDトークンを復号して検証します。検証結果が正しい場合、IDトークンオブジェクトとしてユーザー識別子を取得します。

YConnectClientクラス

メソッド 説明
public boolean verifyIdToken(String nonce, String clientId, String idTokenString)
IDトークンを検証して結果を返却します。
public IdTokenObject decodeIdToken(String idToken)
IDトークンの文字列を復号、検証してIDトークンオブジェクトを取得します。
//IDトークンの検証
if (yconnect.verifyIdToken(nonce, clientId, idTokenString)) {
    // IDトークンを復号
    IdTokenObject idTokenObject = yconnect.decodeIdToken(idTokenString);
} else {
    //検証に失敗したのでエラー文を出力
    String error = yconnect.getCheckErrorMessage();
}

requestTokenメソッドコールの直後にこの復号と検証を行ってください。検証に失敗した場合にはfalseを返却します。正しく検証が行えた場合のみYConnectの認証を認めてください。

各パラメーターはIDトークンオブジェクトのプロパティーに保持されているので必要に応じて参照してください。特別な場合を除き、IDトークンオブジェクト内の情報は保存する必要はありません。

UserInfo APIにリクエストしてユーザー識別子を取得する

アクセストークンを用いてユーザー識別子などを取得します。Authorizationエンドポイントリクエスト時に指定したScopeの情報(姓名・生年・性別、メールアドレス、登録住所情報など)が取得できます。

YConnectClientクラス

メソッド 説明
public void requestUserInfo(String accessTokenString)
UserInfo APIにリクエストします。
public UserInfoObject getUserInfoObject()
ユーザー識別子などをUserInfoオブジェクトとして取得します。
// UserInfo APIへリクエスト
yconnect.requestUserInfo(accessTokenString);
// UserInfo情報を取得
UserInfoObject userInfoObject = yconnect.getUserInfoObject();

各属性情報は必要に応じてUserInfoObjectのプロパティーを参照してください。

アクセストークンを更新する

リフレッシュトークンをつかって有効期限切れのアクセストークンを更新します。

YConnectClientクラス

メソッド 説明
public void refreshToken(String refreshToken, String clientId, String clientSecret)
リフレッシュトークンを用いてTokenエンドポイントにリクエストしアクセストークンを更新します。
// アクセストークンが有効期限切れであるかチェック
if(apiClientException.isInvalidToken()) {
    try {
        // 保存していたリフレッシュトークンを指定してください
        String refreshToken = "STORED_REFRESH_TOKEN";
 
        // Tokenエンドポイントにリクエストしてアクセストークンを更新
        yconnect.refreshToken(refreshToken, clientId, clientSecret);
        String accessTokenString = yconnect.getAccessToken();
        long expiration = yconnect.getAccessTokenExpiration();
    } catch (TokenException tokenException) {
        // リフレッシュトークンの有効期限切れチェック
        if(tokenException.isInvalidGrant()) {
            // はじめのAuthorizationエンドポイントリクエストからやり直してください
        }
    }
}

有効期限切れのアクセストークンでAPI(ここではUserInfo API)にアクセスした場合、内部で例外処理を投げます。保存しておいたリフレッシュトークンでアクセストークンを更新してください。

アクセストークン更新時にリフレッシュトークンが有効期限切れだった場合には、Authorizationエンドポイントのリクエストからやり直してください。

アクセストークンなどの保存について

サーバー側でアクセストークン、リフレッシュトークン、IDトークン、UserInfoAPIから取得した属性情報を保存する場合には外部から読み取られないように保存してください。

アプリケーションの管理

Yahoo! ID連携 v2

開発のヒント