uCosminexus Portal Framework ポートレット開発ガイド

[目次][用語][索引][前へ][次へ]


付録A.10 シングルサインオンのためのポートレット

この例では,統合ユーザ管理フレームワークの提供の機能を利用して,メールサーバにシングルサインオンするポートレットを示します。

<この項の構成>
(1) カスタムログインモジュールの作成
(2) 日立APIポートレット
(3) ポートレットを動作させるための設定

(1) カスタムログインモジュールの作成

まず,メールサーバとのシングルサインオンを実現するために,メールサーバと認証するカスタムログインモジュールを作成します。カスタムログインモジュールでは,sharedStateオブジェクトから,ユーザIDとパスワードを取得して認証します。次の二つのファイルを作成します。

ファイル1
 
package mail;
 
import java.security.Principal;
import java.io.Serializable;
 
public class MailPrincipal implements Principal, Serializable
{
  private String name;
 
  public MailPrincipal(String name) {
    if (name == null) throw new NullPointerException();
    this.name = name;
  }
  public String getName() { return name; }
  public String toString() { return getName(); }
  public boolean equals(Object o) {
    if (o == null) return false;
    if (this == o) return true;
    if (!(o instanceof MailPrincipal)) return false;
    MailPrincipal rhs = (MailPrincipal)o;
    if (getName().equals(rhs.getName())) return true;
    return false;
  }
  public int hashCode() { return getName().hashCode(); }
}
 

ファイル2
package mail.login;
 
import com.cosminexus.admin.auth.*;
 
import javax.security.auth.*;
import javax.security.auth.login.*;
import javax.security.auth.callback.*;
import javax.security.auth.spi.*;
import java.text.*;
import java.util.*;
import javax.mail.*;
import java.util.Properties;
 
import mail.MailPrincipal;
 
public class MailLoginModule implements LoginModule {
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map options;
 
    private static final String USER_HOST_OPT = "mail.login.host";
    private static final String USER_PROV_OPT = "mail.login.provider";
 
    private static final String USERNAME = "mail.login.username";
    private static final String PASSWORD = "mail.login.password";
 
    private static final String DEFAULT_PROV = "imap";
 
    private static final String MSG_USERNOTFOUND = "user not found!";
    private static final String MSG_NOHOSTOPT = "not host option!";
 
    private boolean commitSucceeded = false;
 
    private Store store;
    private String username;
 
    public void initialize(
        Subject subject,
        CallbackHandler callbackHandler,
        Map sharedState,
        Map options)
    {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;
    }
 
    public boolean login()
        throws LoginException
    {
        // get user-name & password
        this.username = (String)this.sharedState.get(USERNAME);
        if (username == null) throw new LoginException(MSG_USERNOTFOUND);
        String password = (String)this.sharedState.get(PASSWORD);
 
        // option check
        String host = (String)this.options.get(USER_HOST_OPT);
        if (host == null || host.length()==0) throw new LoginException(MSG_NOHOSTOPT);
 
        String provider = (String)this.options.get(USER_PROV_OPT);
        if (provider == null ) provider = DEFAULT_PROV;
 
        // login
        Properties props = new Properties();
        Session session = Session.getInstance(props, null);
        try {
            store = session.getStore(provider);
            store.connect(host, username, password);
        } catch(Exception ex) {
            throw new LoginException(ex.toString());
        }
        return true;
    }
 
    public boolean commit() throws LoginException {
        this.subject.getPrincipals().add( new MailPrincipal(this.username) );
        this.subject.getPublicCredentials().add( this.store );
        return this.commitSucceeded = true;
    }
 
    public boolean abort() throws LoginException {
        try {
            if (store != null) store.close();
        } catch(MessagingException ex) {
            // Disregard
        }
        if (this.commitSucceeded) {
            logout();
        }
        return true;
    }
 
    public boolean logout() throws LoginException {
        try {
            if (store != null) store.close();
        } catch(MessagingException ex) {
            // Disregard
        }
        this.commitSucceeded = false;
        return true;
    }
}
 

(2) 日立APIポートレット

次に,メール情報を表示する日立APIポートレットを作成します。このポートレットでは,ログインに成功したあと,subjectからメール情報を取得しています。メール情報を表示するポートレットのサンプルコードを次に示します。

 
<%@ page contentType="text/html; charset=Shift_JIS" %>
<%@ taglib uri="http://cosminexus.com/admin/auth/uatags" prefix="ua" %>
<%@ page import="com.cosminexus.admin.auth.*" %>
<%@ page import="com.cosminexus.admin.auth.sso.callback.*" %>
<%@ page import="javax.security.auth.*" %>
<%@ page import="javax.security.auth.login.*" %>
<%@ page import="java.security.*" %>
<%@ page import="javax.mail.*" %>
<%@ page import="java.util.Properties" %>
 
<%
  LoginContext lc = null;
  try {
    WebSSOHandler h =
      new WebSSOHandler(request, response, null);
    lc = new LoginContext("Mail", h);
    lc.login();
  }
  catch (LoginException e) {
    out.println("Mailへのログインに失敗しました。");
    return;
  }
  catch (Exception e) {
    out.println("Mailへのログインで障害が発生しました。");
    return;
  }
 
  try {
      Subject subject = lc.getSubject();
      Principal principal = (Principal)subject.getPrincipals().
        iterator().next();
      String mailid = principal.getName();
      Store store =
        (Store)subject.getPublicCredentials().iterator().next();
      out.println("メールID="+mailid+"<br />");
      Folder folder = null;
      try {
          folder = store.getFolder("INBOX");
          folder.open(Folder.READ_ONLY);
 
          Message msg[] = folder.getMessages();
          out.println("メール総数="+msg.length+"<br />");
          out.println("<br />");
          if (msg.length == 0) {
              out.println("メールはありません<br />");
          }
          else {
              out.println("メール一覧<br />");
              out.println("<table border>");
              {
                  // 先頭行
                  out.println("<tr>");
                  out.println(
                     "<th><font size=\"4\">項番</th>"
                    +"<th><font size=\"4\">送信者</th>"
                    +"<th><font size=\"4\">メールタイトル</th>");
                  out.println("</tr>");
 
                  // メールのタイトル表示
                  int loop = msg.length>10 ? 10 : msg.length;
                  for (int i = 0; i < loop ; ++i) {
                      out.println("<tr>");
                      out.print("<td align=\"right\">"+(i+1)+"</td>");
                      Address[] addrs = msg[i].getFrom();
                      String requestName = (addrs != null && addrs.length > 0) ?
                        addrs[0].toString() : "不明";
                      out.print("<td>"+requestName+"</td>");
                      out.print("<td>"+msg[i].getSubject()+"</td>");
                      out.println("</tr>");
                  } // for i
              }
              out.println("</table>");
          }
      }
      catch (Exception e) {
           out.println("Mailの表示中に障害が発生しました。");
           return;
      }
      finally {
          try {
              if (folder != null) folder.close(false);
          }
          catch (MessagingException e) { e.printStackTrace(); }
      }
  }
  finally {
      try {
          lc.logout();
      }
      catch (Exception e) {
        out.println("Mailのログオフに障害が発生しました。");
        return;
      }
  }
 
%>
<hr />

(3) ポートレットを動作させるための設定

(2)の日立APIポートレットを動作させるための設定について説明します。

  1. (1)で作成したカスタムログインモジュールをコンパイルして,{Cosminexusインストールディレクトリ}\manager\modulesに格納する
    格納先のディレクトリはユーザ管理コンフィグレーションファイル(ua.conf)のcom.cosminexus.admin.auth.custom.modulesパラメタで変更できます。
  2. JAASコンフィグレーションファイル(jaas.conf)を変更する
    作成したカスタムログインモジュールとポータルのログインモジュールを関連づけるためJAASコンフィグレーションファイル変更します。変更例を次に示します。
     
    Portal {
      com.cosminexus.admin.auth.sso.login.WebSSOLoginModule required
        com.cosminexus.admin.auth.realm="Portal"
        com.cosminexus.admin.auth.ldap.r="0"
        com.cosminexus.admin.auth.ldap.w="1"
        ;
    };
    Mail {
      com.cosminexus.admin.auth.sso.login.WebSSOLoginModule required
        com.cosminexus.admin.auth.sso="MailLM"
        com.cosminexus.admin.auth.realm="Mail"
        mail.login.host="localhost"  /* MailLoginModuleのオプション */
        ;
    };
     
  3. カスタムログインモジュールを統合ユーザ管理に認識させるため,ユーザ管理コンフィグレーションファイル(ua.conf)に次の内容を追記する
    追加内容を次に示します。
     
    com.cosminexus.admin.auth.sso.lm.MailLM=mail.login.MailLoginModule
    com.cosminexus.admin.auth.sso.param.userid.MailLM=mail.login.username
    com.cosminexus.admin.auth.sso.param.secdat.MailLM=mail.login.password
     
  4. ポータルのユーザとメールのユーザのマッピングをCSVファイルに作成し,ssoimportコマンドで登録する
    登録例を次に示します。この例では,ポータルのユーザのuser1は,メールのユーザのmuser1に対応していることを示しています。ポートレットの場合,最初にポータルにログインするため,ポータルのパスワードはマッピング情報に登録する必要がありません。
     
    REALMNAME,USERID,SECRETDATA,PUBLICDATA,LINK_Mail
    Portal,user1,,,muser1
    Mail,muser1,pass1,,

[目次][前へ][次へ]


[他社商品名称に関する表示]

All Rights Reserved. Copyright (C) 2009, 2013, Hitachi, Ltd.
All Rights Reserved. Copyright (C) 2009, 2013, Hitachi INS Software, Ltd.