SSOクライアントの作成(3)ログアウトプロセス内でSSOログアウトを行う

2008/11/21:この記事にあるOpenSSOはかなり古いものです。最近のものを使う際の参考にはならないかもしれませんのでご注意ください。

ここまで書いて思ったのだけれど、SSO(シングルサインオン)関連のキーワードが全然自動リンクにならない。
SSOに関する言及はあまりないのね。
SSOを使いたいという要件がないのかなぁ。


閑話休題


今回の要件では個別のSSOクライアントでログアウトした場合はSSOセッションも無効化する。
ただし、個別のSSOクライアントのセッションがタイムアウトしたタイミングでのSSOセッションの無効化は行っていない。
SSOクライアントのセッションがSSOセッションよりも短い場合、SSOクライアントのセッションスコープに保持した値が失われているにも関わらずユーザーがログインできてしまうため、処理に不整合が発生し得る。

これを回避するには以下のいずれかの方法を実施する必要があるので注意すること。



追記:考えてみるとSSOはリフレッシュされるのでタイムアウト時間を長く設定することは無理そう。また、個別アプリのタイムアウトのタイミングでSSOセッションを無効にすると、他のアプリを操作しているにもかかわらずタイムアウトになってしまう。このあたりは一般的にはどうするんだろう。


で、本題のログアウトの実装については以下のようになる。

// 
// FIXME:LOGとしてログ用インスタンスを取得
// 
public static final String SSOTOKEN_NAME = "ssotoken";
public static final String SET_COOKIE_REQUEST = "SET_COOKIE_REQUEST";
public static final String MODULE_NAME = "DataStore";
public void logout() {
	// SSOクライアントのログアウト
	... 略 ...
	try {
		SSOTokenManager ssoManager = SSOTokenManager.getInstance(); 
		SSOToken ssoToken = ssoManager.createSSOToken(getSSOTokenIdFromCookie()); 
		AuthContext lc = new AuthContext(ssoToken);
		AuthContext.IndexType indexType = AuthContext.IndexType.MODULE_INSTANCE;
		lc.login(indexType, MODULE_NAME);
		lc.logout();
	} catch (Exception e) {
		LOG.error("Logout fail.", e);
		throw new Exception("error");
	}
}
public String getSSOTokenIdFromCookie() {
	// 
	// FIXME:requestとしてHttpServletRequestを取得
	// 
	// このリクエスト内でSSOセッションを生成した場合はrequest内にCookieが
	// ないため、予めrequest属性に設定した値を取得する
	String tokenId = (String) request.getAttribute(SET_COOKIE_REQUEST);
	if (tokenId != null) {
		return tokenId;
	}
	// CookieからSSOTokenのIDを設定
	Cookie[] cookies = request.getCookies();
	Cookie cookie = null;
	for (int i = 0;i < cookies.length;i++) {
		if (cookies[i].getName().equals(SSOTOKEN_NAME)) {
			cookie = cookies[i];
			break;
		}
	}
	return cookie.getValue();
}

SSOTokenを渡してAuthContextを生成しているが、これが本当に正しいのかどうかは謎。