- validateOpenId() - This method is called after the user selects an OpenID provider from the OpenID Selector component on the Login form. The Action then calls the business bean (OpenIdAuthenticator) which generates the destination URL for OpenId Provider. The request is then redirected to the destination URL. It's important to note that we are now redirecting the user away from our web application. Our application never sees or has access to the user's password. The OpenID Provider will let us know if the use has successfully authenticated.
- validateOpenId() - Once the user has successfully authenticated with the OpenID Provider. The Provider redirects the user back to our web application, using the return URL we provided. This method processes that request. Again we pass it off to the business bean and let it confirm the login was successful and glean any relevant information sent by the OpenID Provider. The business bean will return a User object which we'll persist in the database and add to the user's HTTP Session. At this point we'll redirect the user to the resource he was originally requesting before we forced him to authenticate.
public class LoginAction extends FlashCardsAppBaseAction implements Preparable, ServletRequestAware, ServletResponseAware, SessionAware, ApplicationAware {
static Logger logger = Logger.getLogger(LoginAction.class);
// this is the only form field we will be looking for from OpenID Selector on the front end
private String openid_identifier;
// Hibernate Session
private Session hibernateSession;
// we'll need access to the Servlet spec objects, rather than just their attribute or parm maps
private HttpServletRequest request;
private HttpServletResponse response;
// we'll be storing the User object in the Session
private Map<String, Object> httpSession;
// the OpenIdAuthenticator class needs access to the application to store a OpenId4Java related object
private Map<String, Object> application;
// we'll need to send this to the OpenId provider so it knows where to send its response
private final String returnAction = "/home/authenticateOpenId.action";
// the OpenID Selector form will submit to this Action method
public String validateOpenId() throws Exception {
logger.debug("Entering validateOpenId()");
// get rid of trailing slash
if (getOpenid_identifier().endsWith("/")) {
setOpenid_identifier(getOpenid_identifier().substring(0, getOpenid_identifier().length() - 1));
}
logger.debug("The requested OpenId identifier is: " + getOpenid_identifier());
// determine a return_to URL where the application will receive
// the authentication responses from the OpenID provider
String returnUrl = getServerContext(request) + returnAction;
// construct the destination Url to send to the Open Id provider
String destinationUrl = OpenIdAuthenticator.getValidateOpenIdUrl(returnUrl, this.getOpenid_identifier(), httpSession, application);
// redirect to the Auth Request
response.sendRedirect(destinationUrl);
// no need to return a view
return NONE;
}
public String authenticateOpenId() throws Exception {
logger.debug("Entering authenticateOpenId()");
Map<String,String[]> parmList = request.getParameterMap();
// extract the receiving URL from the HTTP request
final StringBuffer receivingURL = request.getRequestURL();
final String queryString = request.getQueryString();
if (queryString != null && queryString.length() > 0) {
receivingURL.append("?").append(request.getQueryString());
}
logger.debug(receivingURL.toString().replaceAll("&", "\n"));
// verify the user has authenticated with the Open Id provider and
// get a reference to the authenticated User
User user = OpenIdAuthenticator.getAuthenticatedUser(parmList, receivingURL, httpSession, application);
// save the user to the DB
UserPersister uPersister = new UserPersister();
uPersister.saveOrUpdateUser(user, hibernateSession);
// add the user to the HTTP Session
httpSession.put("user", user);
// retrieve the original URL from the Session
String desitinationURL = (String)httpSession.get("originalURL");
// was a destination URL provided?
if (desitinationURL == null) {
logger.debug("No destination URL provided, will send to Home");
return "home";
}
else {
logger.debug("Redirecting to : " + desitinationURL);
response.sendRedirect(desitinationURL);
return NONE;
}
}
@SuppressWarnings("rawtypes")
public String logout() {
logger.debug("Entering logout()");
try {
// invalidate the user's session
httpSession.remove("user");
if (httpSession instanceof org.apache.struts2.dispatcher.SessionMap) {
try {
((org.apache.struts2.dispatcher.SessionMap) httpSession).invalidate();
} catch (IllegalStateException e) {
logger.error("Exception in logout()", e);
}
}
return "success";
} catch (Exception e) {
logger.error("Exception in logout():", e);
return "error";
}
}
private String getServerContext(final HttpServletRequest request) {
// Get the base url.
final StringBuilder serverPath = new StringBuilder();
serverPath.append(request.getScheme() + "://");
serverPath.append(request.getServerName());
if (request.getServerPort() != 80) {
serverPath.append(":" + request.getServerPort());
}
serverPath.append(request.getContextPath());
return serverPath.toString();
}
@Override
public void prepare() throws Exception {
logger.debug("Entering prepare()");
hibernateSession = getHibernateSession();
}
public String getOpenid_identifier() {
return openid_identifier;
}
public void setOpenid_identifier(String openid_identifier) {
this.openid_identifier = openid_identifier;
}
@Override
public void setSession(Map<String, Object> httpSession) {
this.httpSession = httpSession;
}
@Override
public void setServletResponse(final HttpServletResponse response) {
this.response = response;
}
@Override
public void setServletRequest(final HttpServletRequest request) {
this.request = request;
}
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
}
In the final post in this series, I'll include the code for the OpenIdAuthenticator business bean which does the heavy lifting and relies heavily on the OpenId4Java library.
No comments:
Post a Comment