package com.googlecode.flickr2twitter.servlet;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.expressme.openid.Association;
import org.expressme.openid.Authentication;
import org.expressme.openid.Endpoint;
import org.expressme.openid.OpenIdException;
import org.expressme.openid.OpenIdManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.googlecode.flickr2twitter.datastore.MyPersistenceManagerFactory;
import com.googlecode.flickr2twitter.datastore.model.User;
import com.googlecode.flickr2twitter.org.apache.commons.lang3.StringUtils;
/**
* Sample servlet using JOpenID.
*
* @author Michael Liao (askxuefeng@gmail.com)
*/
public class OpenIdServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(OpenIdServlet.class);
/**
*
*/
private static final long serialVersionUID = 1L;
public static final long ONE_HOUR = 3600000L;
public static final long TWO_HOUR = ONE_HOUR * 2L;
public static final String ATTR_MAC = "openid_mac";
public static final String ATTR_ALIAS = "openid_alias";
public static final String ATTR_OP = "op";
public static final String ATTR_OPENID_RESPONSE_NONCE = "openid.response_nonce";
public static final String ID_GOOGLE = "Google";
public static final String ID_YAHOO = "Yahoo";
private OpenIdManager manager;
@Override
public void init() throws ServletException {
super.init();
manager = new OpenIdManager();
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String baseurl = request.getRequestURL().toString();
if (log.isDebugEnabled()) {
log.debug("Base URL: {}", baseurl);
}
manager.setRealm(StringUtils.substringBeforeLast(baseurl, "/"));
manager.setReturnTo(baseurl);
String op = request.getParameter(ATTR_OP);
if (op == null) {
log.info("check sign on result from Google or Yahoo");
checkNonce(request.getParameter(ATTR_OPENID_RESPONSE_NONCE));
// get authentication:
byte[] mac_key = (byte[]) request.getSession().getAttribute(ATTR_MAC);
String alias = (String) request.getSession().getAttribute(ATTR_ALIAS);
Authentication authentication = manager.getAuthentication(request, mac_key, alias);
response.setContentType("text/html; charset=UTF-8");
String userEmail = authentication.getEmail();
User user = MyPersistenceManagerFactory.getOpenIdLoginUser(userEmail);
if (user == null) {
//not a registered user
log.info("New open ID user, try to automatically register->{}", userEmail);
user = MyPersistenceManagerFactory.createNewUser(userEmail, "openid", authentication.getFullname());
}
request.getSession().setAttribute(UserAccountServlet.PARA_SESSION_USER, user);
response.sendRedirect("/index.jsp");
return;
}
if (op.equals(ID_GOOGLE) || op.equals(ID_YAHOO)) {
log.info("redirect to {} sign on page", op);
Endpoint endpoint = manager.lookupEndpoint(op);
Association association = manager.lookupAssociation(endpoint);
request.getSession().setAttribute(ATTR_MAC, association.getRawMacKey());
request.getSession().setAttribute(ATTR_ALIAS, endpoint.getAlias());
String url = manager.getAuthenticationUrl(endpoint, association);
response.sendRedirect(url);
}
else {
throw new ServletException("Unsupported OP: " + op);
}
}
void checkNonce(String nonce) {
// check response_nonce to prevent replay-attack:
if (nonce==null || nonce.length()<20)
throw new OpenIdException("Verify failed.");
// make sure the time of server is correct:
long nonceTime = getNonceTime(nonce);
long diff = Math.abs(System.currentTimeMillis() - nonceTime);
if (diff > ONE_HOUR)
throw new OpenIdException("Bad nonce time.");
}
long getNonceTime(String nonce) {
try {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.parse(nonce.substring(0, 19) + "+0000")
.getTime();
}
catch(ParseException e) {
throw new OpenIdException("Bad nonce time.");
}
}
}