이 글은 다음글에 이어진 글입니다.
Java로 OpenID Consumer 서비스 구현하기 #1 : OpenID란?
Java로 OpenID Consumer 서비스 구현하기 #2 : OpenID4Java로 인증요청하기
인증 요청까지 했으니까 이제 인증확인을 할 차례이다. 인증작업이야 OpenID의 원리상 요청에서 잘못된게 없다면 OP측에서 알아서 다 해준 다음에 내가 정해준 returnToUrl로 준 경로로 End-User가 돌아오게 된다.(인증정보를 가진채...) 이제 내가 기대한 인증정보와 End User가 가지고 돌아온 인증정보를 비교해서 제대로 인증을 받았는지만 확인하면 된다.
// resultOpenid.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<% request.setCharacterEncoding("utf-8"); %>
<% response.setContentType("text/html; charset=utf-8"); %>
<%@ page import="org.openid4java.discovery.Identifier" %>
<%@ page import="kr.test.openid.SampleConsumer" %>
<%
SampleConsumer sc = (SampleConsumer)application.getAttribute("cm");
Identifier ver = sc.verifyResponse(request);
if (ver != null) {
out.println(ver.getIdentifier() + "님 환영합니다.");
} else {
out.println("로그인에 실패하였습니다.");
}
%>
위의 소스가 returnToUrl의 페이지 소스이다. 머 간단하다.. ㅎ SampleConsumer의 객체를 만들로 인증확인 메서드인 verifyResponse를 호출하고 현재의 request를 파라미터로 넘겨준다. 리턴값으로 Identifier를 받는다. 인증이 실패하면 받아온 Identifier가 null로 나오고 null이 아니면 getIdentifier()함수를 이용해서 OpenID를 가져온다. getIdentifier()함수가 http://rockdoli.myid.net/형태의 오픈아이디를 리턴해 준다.
여기서 주의할점은 7번째줄이다. 이전글에서 SampleConsumer객체를 만든 뒤에 application에 할당한 것을 기억할 것이다. 인증을 확인 하려면 인증을 요청할 때와 확인할 때의 SampleConsumer객체가 동일한 객체여야 인증확인이 가능하다. 두 객체가 다른 객체일 경우에는 ver이 무조건 null이 나온다.(rath님의 강좌 하단 FAQ참조) rath님의 경우는 이걸 해결하기 위해서 서블릿을 사용해서 해결하였지만 나는 약간의 상황적인 문제도 있었고 서블릿에 아주 약하기 때문에 서블릿으로 해결하지 못하고 고민하다가 application객체를 이용했다. 서블릿을 이용한 방법이 더 좋다고 생각하지만 application객체를 이용한 것도 동작에는 아무 이상이 없다. ㅎㅎㅎ
이제 verifyResponse를 보자. verifyResponse도 authRequest와 같이 SampleConsumer클래스의 메서드이다.
// SampleConsumer.java
public Identifier verifyResponse(HttpServletRequest httpReq) {
try {
ParameterList response = new ParameterList(httpReq.getParameterMap());
DiscoveryInformation discovered = (DiscoveryInformation)httpReq.getSession().getAttribute("openid-disc");
StringBuffer receivingURL = httpReq.getRequestURL();
String queryString = httpReq.getQueryString();
if (queryString != null && queryString.length() > 0) {
receivingURL.append("?").append(httpReq.getQueryString());
}
VerificationResult verification = manager.verify(receivingURL.toString(), response, discovered);
Identifier verified = verification.getVerifiedId();
if (verified != null) {
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
}
return verified; // success
}
} catch (OpenIDException e) {
System.out.println("################## : error");
}
return null;
}
인증을 확인하는 메서드이다. 실제 인증을 확인하는 부분은
VerificationResult verification = manager.verify(receivingURL.toString(), response, discovered);
이다. 앞에서도 말했듯이 소스의 내용을 다 설명하기에는 내 내공으론 무리다.. ㅎㅎㅎㅎㅎ
처음이 어려워서 그렇지 막상하면 크게 어려운 부분은 없다.(의미를 모른채 그냥 쓰는거니까.. ㅡ..ㅡ) 어쨌든 이렇게 해서 다음과 같은 메시지를 보면 성공한 것이다.
이렇게 길게 써본적이 없는데 글의 특성상 글이 점점 길어지는군.... ㅎ 다음편에는 추가정보 요청에 대해서.. ㅡ..ㅡ
글 잘 보았습니다.
저도 rath님 글을 보고 따라하다가 영 버전대문에 막히던 차에 outsider님이 올려주신 글 보고 나름 빨리(?)해결책을 찾았네요.
저도 메소드와 소스 해석이 아직 되지 않아서 추가정보 요청에서도 헤메고 있네요;;
로그아웃도 구현해 볼려고 하는데 영 쉽지가 않습니다 ㅡㅋ
조금식 정보를 모으는데로 다시 다시 들어오도록 하겠습니다.
도움되셨다니 다행이네요.
저도 겨우 구현만 한터라...
추가요청정보는 이번주에 시간나는대로 글을 더 쓰려고 했습니다만 SimpleRegistration을 이용하시면 됩니다.
로그아웃은 그냥 저희 사이트쪽에서만 로그아웃을 했습니다만...
안되시는 부분 빨리 해결하시길 바라고 좋은 정보 얻으시면 공유부탁드립니다. ^^