arcanum_jp’s blog

おっさんの日記

OpenID with Wicketその3


追記、このページを見つけてくださった方へ。このページで書いている問題はhttp://d.hatena.ne.jp/nigredo/20090121/1232548821にて解決されています。合わせてご覧ください。

 今日はベリファイ処理。こちらでメモったけど、WicketOpenIDを使うための手順。一応これでやってみました。(※下は、やってみた感想としてできない方法が初めに提示しています。ご注意ください。)



Wicket with Openid
http://d.hatena.ne.jp/nigredo/20081112/1226501949


 OpenIDプロバイダに設定する返送URLを、たとえばVerifyPageとし、コンストラクタでPageParametersを指定するって方法です。

 
ログインボタン処理の時点ではVerifyPage側に送るべく引数は存在しない(わからない)のでnullを設定しています。

String returnURL = (String)urlFor(VerifyPage.class,null);
returnURL = RequestUtils.toAbsolutePath(returnURL);

AuthRequest authReq = manager.authenticate(discovered, returnURL);
if(authReq != null){
	getRequestCycle().setRequestTarget(new RedirectRequestTarget(authReq.getDestinationUrl(true)));
}


VerifyPage側では・・・コンストラクタで、OpenIDプロバイダからコールバックされた際のクエリストリングの妥当性を判断します。

public class VerifyPage extends AbstractPage{

	
	public VerifyPage(PageParameters params){
		
		MySession sess = (MySession)getSession();
		
		// manager
		ConsumerManager manager = ConsumerManagerWrapper.getInstance();
		
		// openidResp
		HttpServletRequest request = ((WebRequest) RequestCycle.get().getRequest()).getHttpServletRequest();
		ParameterList openidResp = new ParameterList(request.getParameterMap());
		
		// get stored discoveryInfomation object
		DiscoveryInformation discovered = sess.getDescoveryInformation();
		
		// receivingURL
		StringBuffer receivingURL = request.getRequestURL();
		String queryString = request.getQueryString();
		if (queryString != null && queryString.length() > 0){
			receivingURL.append("?").append(request.getQueryString());
		}

		VerificationResult verification = null;
		try{
			verification = manager.verify(receivingURL.toString(), openidResp, discovered);
		}catch(Exception e){
			e.printStackTrace();
		}
		Identifier verified = null;
		if(verification!=null){
			verified = verification.getVerifiedId();
		}
		if (verified != null){
			// ログイン成功後のページに遷移
			setResponsePage(AfterLoginedPage.class);
			
		}else{
			//エラーページ何なりに遷移
			setResponsePage(VerifyErrorPage.class);
			
		}

		・・・VerifyPageのコンストラクタ処理
		
		
	}
	
}

 一応、OpenIDプロバイダまではこれで行きました。でも、今度はVerifyPage側のコンストラクタで、エラーで止まってしまいました。間違ったパラメータがセットされたんだと・・・でも何がなんだか私にはわからん・・・

org.openid4java.message.MessageException: Invalid set of parameters for the requested message type
	at org.openid4java.message.AuthSuccess.createAuthSuccess(AuthSuccess.java:116)
	at org.openid4java.consumer.ConsumerManager.verify(ConsumerManager.java:1110)
	at jp.arcanum.xxxxx.yyyyyyZzzzPage.<init>(ZzzzPage.java:91)

    ... 省略
    

なんで!!



 ※こっから試行錯誤してできた方法です。


 2日ほど何がなんだか分からずに考え込んでいたんですが、先のURLを読む前に考えていた方法をやってみました。方法は簡単で、OpenIDプロバイダに設定する返送URLをサイトトップにします(これはWebApplication#getHomePage()で取得できるページです)で、コンストラクタ処理で、OpenIDプロバイダからのコールバックであれば、ベリファイ処理を行うと・・・こんな感じ。
 
 
まず、ログインボタンで・・・

// サイトトップを返送URLに設定
String returnURL = RequestUtils.toAbsolutePath("");
AuthRequest authReq = manager.authenticate(discovered, returnURL);
if(authReq != null){
	getRequestCycle().setRequestTarget(new RedirectRequestTarget(authReq.getDestinationUrl(true)));
}

 つぎに、サイトトップページのコンストラクタ処理で・・・
 


public HogePage(){

	MySession sess = (MySession)getSession();
	
	// manager
	ConsumerManager manager = ConsumerManagerWrapper.getInstance();
	
	// openidResp
	// ↓は、Wicketからもっといい方法で情報を取得する方法があるとは思うけど、思いつかなかったので
	HttpServletRequest request = ((WebRequest) RequestCycle.get().getRequest()).getHttpServletRequest();
	ParameterList openidResp = new ParameterList(request.getParameterMap());
	
	// get stored discoveryInfomation object
	DiscoveryInformation discovered = sess.getDescoveryInformation();
	
	// receivingURL
	StringBuffer receivingURL = request.getRequestURL();
	String queryString = request.getQueryString();

	// サイトへのクエリ文字列があった場合は、OpenIDプロバイダからのコールバックかもしれない
	if (queryString != null){
		
		if ( queryString.length() > 0){
			receivingURL.append("?").append(request.getQueryString());
		}

		VerificationResult verification = null;
		try{
			verification = manager.verify(receivingURL.toString(), openidResp, discovered);
		}catch(Exception e){
			e.printStackTrace();
		}
		Identifier verified = null;
		if(verification!=null){
			verified = verification.getVerifiedId();
		}
		if (verified != null){
			// ログイン成功後のページに遷移
			setResponsePage(AfterLoginedPage.class);
			
		}else{
			//エラーページ何なりに遷移
			setResponsePage(VerifyErrorPage.class);
			
		}
		return;
	}
	

	・・・サイトトップのコンストラクタの処理

 OpenIDプロバイダからのコールバック判定に、単にnullかどうか指定していますが、この場合だと、間違ってクエリストリングを指定した場合も条件に合ってしまいます。その辺の条件式をもうちょっと考えるべきだとは思うのですが、とりあえず、これでできました。


 さぁ、できたのでもう寝るぞ・・・zzz