シングル・サインオンJavaAPIを利用するプログラムの開発方法について説明します。シングル・サインオンJavaAPIはJAASのフレームワークを利用しています。
サンプルコードSampleServlet.javaの例を用いて処理を説明します。このサンプルコードは、クライアントからすでに認証済みであることを証明する認証情報を受け取り、認証した利用者の情報を表示するサーブレットアプリケーションです。
import java.io.IOException; import java.io.PrintWriter; import java.io.OutputStreamWriter; import java.security.Principal; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fujitsu.interstage.sso.auth.ISAuthorizationCredential; import com.fujitsu.interstage.sso.auth.callback.ISCallbackHandler; public class SampleServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); response.setContentType("text/html; charset=Shift_JIS"); Cookie cookie = null; Cookie[] cookies = request.getCookies(); if (cookies != null){ for (int i=0; i< cookies.length;i++){ if (cookies[i].getName().equals( ISAuthorizationCredential.COOKIE_KEY)){ cookie = cookies[i]; } } } if (cookie == null ){ out.println("<html>"); out.println("<body>"); out.println("No cookie information"); out.println("</body>"); out.println("</html>"); return; } String credentialStr = cookie.getValue(); LoginContext context = null; try{ // CallbackHandlerのインスタンス化 CallbackHandler myHandler = new ISCallbackHandler(credentialStr); // LoginContextのインスタンス化 context = new LoginContext( "com.fujitsu.interstage.sso",myHandler); // LoginContextのloginメソッドの呼び出し context.login(); } catch(Exception ex){ out.println("<html>"); out.println("<body>"); out.println("Exception : " + ex.getMessage()); out.println("</body>"); out.println("</html>"); return; } // ユーザ情報の取得 Subject subject = context.getSubject(); Set principals = subject.getPrincipals(); // display principal information out.println("<html>"); out.println("<body>"); out.println("<table>"); Iterator p_iterator = principals.iterator(); while (p_iterator.hasNext()) { Principal principal = (Principal)p_iterator.next(); out.println("<tr>"); out.println("<td>" + principal.getClass().getName() + "</td>"); out.println("<td>" + principal.getName() + "</td>"); out.println("</tr>"); } out.println("</table>"); out.println("</body>"); out.println("</html>"); } } |
JAASを使用するにはCallbackHandlerをインスタンス化する必要があります。シングル・サインオンJavaAPIではCallbackHandler実装クラスを提供しています。クラス名はcom.fujitsu.interstage.sso.auth.callback.ISCallbackHandlerです。認証に必要な情報はCallbackHandlerからCallbackを介してLoginModuleへ渡されます。
ISCallbackHandlerをクライアントから取得したSSO認証済み情報でインスタンス化します。SSO認証済み情報はCookieに格納されています。Cookieのキー名は“fj-is-sso-credential”です。キー名は、com.fujitsu.interstage.sso.auth.ISAuthorizationCredentialクラスのCOOKIE_KEY変数に定義されています。
コードを以下に示します。
Cookie cookie = null; Cookie[] cookies = request.getCookies(); if (cookies != null){ for (int i=0; i< cookies.length;i++){ if (cookies[i].getName().equals( ISAuthorizationCredential.COOKIE_KEY)){ cookie = cookies[i]; } } } String credentialStr = cookie.getValue(); CallbackHandler myHandler = new ISCallbackHandler(credentialStr); |
次に、LoginContextのインスタンス化を行います。コードを以下に示します。
LoginContext Context = new LoginContext("com.fujitsu.interstage.sso", myHandler); |
LoginContextを以下の引数を指定して、インスタンス化します。
第1引数
ログイン構成ファイルのエントリ名。
ログイン構成ファイルについては、“6.1.3.2 ログイン構成ファイルの作成”を参照してください。
第2引数
“6.1.2.1 CallbackHandlerのインスタンス化”でインスタンス化したインスタンス。
LoginContextのloginメソッドを呼び出すことで認証処理が行われます。loginメソッドではLoginException、またはそのサブクラスがスローされますので、そのcatch処理を行います。
コードを以下に示します。
try{ loginContext.login(); } catch(FailedLoginException ex){ System.out.println("Authenticate failed"); continue; } |
JAAS認証に成功した場合、復帰値のSubjectオブジェクトに対して以下のオブジェクトが関連付けられます。
認証された利用者のユーザIDを表すPrincipalオブジェクト
利用者が属するロール名を表すPrincipalオブジェクト
SSOリポジトリ内の一意の識別名を表すPrincipalオブジェクト
PrincipalオブジェクトはSubjectオブジェクトの以下のメソッドで取得することができます。
public Set getPrincipals();
public Set getPrincipals(Class c);
この2つのメソッドの違いはgetPrivateCredentialsメソッドと同様です。関連付けられるオブジェクトのクラスを以下に示します。
クラス名 | 説明 |
com.fujitsu.interstage.sso.auth.ISUserPrincipal | 認証された利用者のユーザIDを表します。 |
com.fujitsu.interstage.sso.auth.ISRolePrincipal | 利用者が属するロール名を表します。利用者がロールセットに属する場合、ロールセットに含まれるロールがそれぞれISRolePrincipalのオブジェクトとして関連付けられます。このオブジェクトは利用者がロールに属さない場合は設定されません。 |
javax.security.auth.x500.X500Principal | 利用者のSSOリポジトリ内の一意の識別名(DN)を表します。 |
コードを以下に示します。
Set principals = subject.getPrincipals(); iterator = principals.iterator(); while (iterator.hasNext()) { Principal principal = (Principal)iterator.next(); System.out.println("Principal=" + principal.getClass().getName()); System.out.println(principal.getName()); } |
■通知されるユーザ情報について
業務サーバの定義を使用して認証先の認証サーバを指定する場合、ISAuthorizationCredentialオブジェクト内に保持する以下の情報は、Interstage管理コンソールで設定する[ユーザ情報の通知]の設定を“通知する”にした場合に通知されます。
利用者のDN
ロール名
認証方式
利用者のUID
クライアントのIPアドレス
認証時刻
再認証時刻
拡張ユーザ情報
[ユーザ情報の通知]については、Interstage管理コンソールを使用して、[システム] > [セキュリティ] > [シングル・サインオン] > [業務システム] > [業務システム名] > [環境設定]タブ > [詳細設定[表示]]をクリックし、[Webアプリケーションとの連携]の[ユーザ情報の通知]を確認してください。この設定の詳細については、Interstage管理コンソールのヘルプを参照してください。
[ユーザ情報の通知]の設定の反映には、IJServerクラスタの再起動が必要です。IJServerクラスタを再起動してください。ログイン構成については、“6.1.3.2 ログイン構成ファイルの作成”を参照してください。
拡張ユーザ情報については、Interstage管理コンソールを使用して、[システム] > [セキュリティ] > [シングル・サインオン] > [認証基盤] > [リポジトリサーバ] > [環境設定]タブ > [リポジトリサーバ詳細設定[表示]]をクリックし、[業務システムに通知する情報]の[拡張ユーザ情報]を確認してください。この設定の詳細については、Interstage管理コンソールのヘルプを参照してください。
■再認証の間隔が無期限のユーザ情報の通知について
ISAuthorizationCredentialオブジェクトのgetExpirationメソッドを使用して再認証の間隔を取得できますが、再認証の間隔が無期限の場合には、getExpirationで取得される時刻とgetAuthTimeメソッドで取得される時刻は同じ値になります。