SAStrutsでOpenID認証してみた
openid4java -
OpenID 2.0 Java Libraries - Google Project Hosting
を参考にして作ったが、verifyが一向に通らない。
verification = consumerManager.verify(url, openidResp, discovered);
で使用するURLなんですが、サンプルではrequest.getRequestURLから取得しているんですが、cubbyだと返ってくる値が実際のパスとは違っていてエラーになりました。仕方ないんで固定値を設定しています。
うーん、SAStrutsでも違うのかなと思って見てみると、SAStrutsでも取得しているURLは違うみたい。
ここは同じように固定値にしたが、それでも通らない。
色々調べた結果、どうやらrequest.getQueryString()が書き換わっている様子。
request.getAttribute("javax.servlet.forward.query_string");
ここから取るみたい。
以下、ソース。
ConsumerManager はcomponentにSingletonで定義してあります。
あとMayaaと最新のOpenID4Javaで使っているnekoHtmlのバージョンが違うため、0.9.3を使用しています。最新のはSVNから引っ張ってきてantでbuildすればできます。
0.9.4でRealmVerifierのエラーが出た場合は、consumerManagerをnewした後に以下を設定しておけばOK。
http://code.google.com/p/openid4java/issues/detail?id=45&can=1&q=Realm
RealmVerifier verifier = new RealmVerifier(); verifier.setEnforceRpId(false); consumerManager.setRealmVerifier(verifier);
public class LoginAction { @Resource protected ConsumerManager consumerManager; @Resource protected HttpServletRequest request; @Resource protected HttpServletResponse response; /** 入力 */ @Required(target = "openid") public String openidUrl; @Required(target = "hatena") public String hatenaid; private final static String targetURL = "http://localhost:8080/openid/login/verify"; @Execute(validator = false) public String index() { return "login.html"; } @Execute(validator = true, input = "login.html") public String openid() { AuthRequest authReq = auth(openidUrl); if (authReq != null) { try { response.sendRedirect(authReq.getDestinationUrl(true)); return null; } catch (IOException e) { // TODO present error to the user } } return "/error/?redirect=true"; } @Execute(validator = true, input = "login.html") public String hatena() { String discoverUrl = "http://www.hatena.ne.jp/" + hatenaid + "/"; AuthRequest authReq = auth(discoverUrl); if (authReq != null) { try { response.sendRedirect(authReq.getDestinationUrl(true)); return null; } catch (IOException e) { // TODO present error to the user } } return "../?redirect=true"; } private AuthRequest auth(String discoverUrl) { try { List discoveries = consumerManager.discover(discoverUrl); DiscoveryInformation discovered = consumerManager.associate(discoveries); request.getSession().setAttribute("openid-disc", discovered); SRegRequest sregReq = SRegRequest.createFetchRequest(); sregReq.addAttribute("email", true); AuthRequest authReq = consumerManager.authenticate(discovered, targetURL); authReq.addExtension(sregReq); return authReq; } catch (OpenIDException e) { // TODO present error to the user } return null; } @Execute(validator = false) public String verify() { try { ParameterList response = new ParameterList(request.getParameterMap()); DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute( "openid-disc"); StringBuilder receivingURL = new StringBuilder(targetURL); String queryString = (String)request.getAttribute("javax.servlet.forward.query_string"); if (queryString != null && queryString.length() > 0) receivingURL.append("?").append(queryString); VerificationResult verification = consumerManager.verify( receivingURL.toString(), response, discovered); Identifier verified = verification.getVerifiedId(); if (verified != null) { AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse(); if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) { MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG); if (ext instanceof SRegResponse) { SRegResponse sregResp = (SRegResponse) ext; String email = sregResp.getAttributeValue("email"); System.out.println("EMAIL:" + email); } } System.out.println("SUCCESS"); return "registration.html"; // success } } catch (OpenIDException e) { // TODO present error to the user } return "registration.html"; } }