Yahoo! ID連携

Java SDK

Java SDK

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

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



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

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

  • jp.co.yahoo.yconnect


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

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

YConnectExplicitクラス

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

OAuth2ResponseTypeクラス

定義フィールド値 説明
public static final String CODE 認可コードを取得するための定数です。
public static final String CODE_IDTOKEN 認可コードとIDトークンを取得するための定数です。

OIDCDisplayクラス

定義フィールド値 説明
public static final String DEFAULT パソコン版のテンプレートを表示するための定数です。
public static final String SMART_PHONE スマートフォン版のテンプレートを表示するための定数です。

OIDCPromptクラス

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

OIDCScopeクラス

定義フィールド値 説明
public static final String OPENID ユーザー識別子を取得するための定数です。
public static final String PROFILE 姓名・生年・性別を取得するための定数です。
public static final String EMAIL メールアドレスと確認済みフラグを取得するための定数です。
public static final String ADDRESS ユーザー登録住所情報を取得するための定数です。
YConnectServlet.java
// アプリケーションID、シークレット
private final static String clientId = "YOUR_APPLICATION_ID";
private final static String clientSecret = "YOUR_SECRET";

// コールバックURL
// (アプリケーションID発行時に登録したURL)
private static final String redirectUri = "http://YOUR_CALLBACK_HOST/YConnectServlet/YConnectServlet";

// state、nonceにランダムな値を初期化
String state = "5Ye65oi744KKT0vjgafjgZnjgojjgIHlhYjovKnjg4M="; // リクエストとコールバック間の検証用のランダムな文字列を指定してください
String nonce = "SUTljqjjga8uLi7jgrrjg4Plj4vjgaDjgoc="; // リプレイアタック対策のランダムな文字列を指定してください

// YConnectインスタンス取得
YConnectExplicit yconnect = new YConnectExplicit();

// 各パラメーター初期化
String responseType = OAuth2ResponseType.CODE_IDTOKEN;
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);
URI uri = yconnect.generateAuthorizationUri();

// Authorizationエンドポイントにリダイレクト(同意画面を表示)
response.sendRedirect(uri.toString());

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

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



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

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

YConnectExplicitクラス

メソッド 説明
public boolean hasAuthorizationCode(String query) QueryStringの文字列から認可コードを抽出し有無を確認します。
public boolean hasAuthorizationCode(Uri uri) QueryStringが含まれるUriから認可コードを抽出し有無を確認します。
public String getAuthorizationCode(String state) リクエスト時とコールバック時のstateの値を検証し認可コードを取得します。
YConnectServlet.java
// コールバックURLから各パラメーターを抽出
if(yconnect.hasAuthorizationCode(query)) {

    // 認可コードを取得
    String code = yconnect.getAuthorizationCode(state);

}

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



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

取得した認可コードを用いてアクセストークン、リフレッシュトークンを取得します。Authorizationエンドポイントリクエストのレスポンスタイプに「CODE_IDTOKEN」を指定している場合にはIDトークンを取得できます。

YConnectExplicitクラス

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


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

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

YConnectExplicitクラス

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

requestTokenメソッドコールの直後にこの復号と検証を行ってください。検証に失敗した場合には内部で例外処理を投げます。正しく検証が行えた場合のみYConnectの認証を認めてください。

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



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

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

YConnectExplicitクラス

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

各パラメーターはUserInfoオブジェクトのプロパティーに保持されているので必要に応じて参照してください。



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

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

YConnectExplicitクラス

メソッド 説明
public void refreshToken(String refreshToken, String clientId, String clientSecret) リフレッシュトークンを用いてTokenエンドポイントにリクエストしアクセストークンを更新します。
YConnectServlet.java
// アクセストークンが有効期限切れであるかチェック
if(ace.isInvalidToken()) {
    try {
        // 保存していたリフレッシュトークンを指定してください
        String refreshToken = "STORED_REFRESH_TOKEN";

        // Tokenエンドポイントにリクエストしてアクセストークンを更新
        yconnect.refreshToken(refreshToken, clientId, clientSecret);
        String accessTokenString = yconnect.getAccessToken();
        long expiration = yconnect.getAccessTokenExpiration();
    } catch (TokenException te) {
        // リフレッシュトークンの有効期限切れチェック
        if(te.isInvalidGrant()) {
            // はじめのAuthorizationエンドポイントリクエストからやり直してください
        }
    }
}

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

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



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

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



Yahoo!知恵袋で調べる