According to the OpenId4Java website, the OpenId4Java library "allows you to OpenID-enable your Java webapp." Many thanks to the folks who put together this solid library. I suggest checking out the sample code. There's a number of example that will help you get started.
One of the tricky things I encountered was managing to get the OpenId provider to provide information about the logged in user. Things like the user's first and last name, their email address, country, and language. I was disappointed to discover the OpenID Providers (Google, Yahoo, AOL, etc) are not consistent in the level of detail they provide about the user. Not only that but the format of the attributes are different as well. This difference leads to the if/else section of the getValidateOpenIdUrl() method.
public class OpenIdAuthenticator {
static Logger logger = Logger.getLogger(OpenIdAuthenticator.class);
private static ConsumerManager getConsumerManager(Map<String, Object> application) {
logger.debug("Entering getConsumerManager()");
ConsumerManager manager;
// try to get the ConsumerManager from the Application scope
manager = (ConsumerManager)application.get("consumermanager");
if (manager == null) {
// create a new ConsumerManager
try {
manager = new ConsumerManager();
manager.setAssociations(new InMemoryConsumerAssociationStore());
manager.setNonceVerifier(new InMemoryNonceVerifier(5000));
} catch (Exception e) {
e.printStackTrace();
}
// add the Consumer Manager to the application scope
application.put("consumermanager", manager);
}
return manager;
}
@SuppressWarnings("unchecked")
public static String getValidateOpenIdUrl(String returnUrl, String openIdIdentifier, Map<String, Object> httpSession, Map<String, Object> application) throws DiscoveryException,
MessageException, ConsumerException {
logger.debug("Entering getOpenIdDestinationUrl()");
// get a reference to the Consumer Manager
ConsumerManager manager = getConsumerManager(application);
// perform discovery on the user-supplied identifier
List<DiscoveryInformation> discoveries = manager.discover(openIdIdentifier);
// attempt to associate with the OpenID provider
// and retrieve one service endpoint for authentication
DiscoveryInformation discovered = manager.associate(discoveries);
// store the discovery information in the user's session for later use
// leave out for stateless operation / if there is no session
httpSession.put("discovered", discovered);
// obtain a AuthRequest message to be sent to the OpenID provider
AuthRequest authReq = manager.authenticate(discovered, returnUrl);
// Attribute Exchange
FetchRequest fetch = FetchRequest.createFetchRequest();
// different Open Id providers accept different attributes
if (openIdIdentifier.contains("google.com")) {
logger.debug("Open Id Identifier is: google.com");
fetch.addAttribute("first", "http://axschema.org/namePerson/first", true);
fetch.addAttribute("last", "http://axschema.org/namePerson/last", true);
fetch.addAttribute("email", "http://axschema.org/contact/email", true);
fetch.addAttribute("language", "http://axschema.org/pref/language", true);
}
else if (openIdIdentifier.contains("yahoo.com")) {
logger.debug("Open Id Identifier is: yahoo.com");
fetch.addAttribute("fullname", "http://axschema.org/namePerson", true);
fetch.addAttribute("nickname", "http://axschema.org/namePerson/friendly", true);
fetch.addAttribute("email", "http://axschema.org/contact/email", true);
fetch.addAttribute("language", "http://axschema.org/pref/language", true);
}
else if (openIdIdentifier.contains("aol.com")) {
logger.debug("Open Id Identifier is: aol.com");
fetch.addAttribute("first", "http://axschema.org/namePerson/first", true);
fetch.addAttribute("last", "http://axschema.org/namePerson/last", true);
fetch.addAttribute("email", "http://axschema.org/contact/email", true);
fetch.addAttribute("language", "http://axschema.org/pref/language", true);
}
else {
logger.debug("Open Id Identifier is: something else");
fetch.addAttribute("fullname", "http://schema.openid.net/namePerson", true);
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
fetch.addAttribute("country", "http://axschema.org/contact/country/home", true);
}
// attach the extension to the authentication request
authReq.addExtension(fetch);
logger.info("The request string is: " + authReq.getDestinationUrl(true).replaceAll("&", "\n"));
return authReq.getDestinationUrl(true);
}
public static User getAuthenticatedUser(Map<String,String[]> parmList,
final StringBuffer receivingURL, Map<String, Object> httpSession, Map<String, Object> application)
throws MessageException, DiscoveryException, AssociationException {
logger.debug("Entering getAuthenticatedUser()");
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList openidResp = new ParameterList(parmList);
// retrieve the previously stored discovery information
final DiscoveryInformation discovered = (DiscoveryInformation) httpSession.get("discovered");
// get a reference to the Consumer Manager
ConsumerManager manager = getConsumerManager(application);
// verify the response
final VerificationResult verification = manager.verify(receivingURL.toString(), openidResp, discovered);
// examine the verification result and extract the verified identifier
Identifier verified = verification.getVerifiedId();
if (verified == null) {
return null;
}
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
User user = new User();
user.setOpenid(authSuccess.getIdentity());
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
logger.info("Processed as OPENID_NS_AX");
FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
// populate the User object with attributes from the FetchResponse
user.setNickname(fetchResp.getAttributeValue("nickname"));
user.setEmail(fetchResp.getAttributeValue("email"));
user.setFullName(fetchResp.getAttributeValue("fullname"));
user.setFirstName(fetchResp.getAttributeValue("first"));
user.setLastName(fetchResp.getAttributeValue("last"));
user.setLanguage(fetchResp.getAttributeValue("language"));
user.setCountry(fetchResp.getAttributeValue("country"));
logger.info("User: " + user.toString());
}
if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
logger.info("Processed as OPENID_NS_SREG");
SRegResponse sregResp = (SRegResponse) authSuccess.getExtension(SRegMessage.OPENID_NS_SREG);
// if we didn't get the user's email addy from the FetchResponse, try to get it from the SRegResponse
if (StringUtils.isBlank(user.getEmail())) {
user.setEmail(sregResp.getAttributeValue("email"));
}
}
return user;
}
}
Thanks a lot,
ReplyDeleteIt really helped me understand the steps of implementation of OpenId with Struts2... gonna try it now....in my project.... was short of puzzled after reading lots of other online contents and ways of implementations. Really thanks for a short and useful guide.
You should be writing more of these implementation guides... its a long time no updates....
sushant, i'm glad you found the post helpful
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi, Thank you for detailed post in this. Would you have the working version of this project, it will be really helpful to run through the flow. Thanks :)
ReplyDeleteregards,
Vasanth.
Really thanks ....it helped me a lot please provide the source code download for this...
ReplyDeleteYou can find an implementation of this in my Github project. https://github.com/justinhrobbins/FlashCards_App/blob/master/FlashCards_Struts/src/main/java/org/robbins/openid/authentication/OpenId4JavaAuthenticator.java
ReplyDeleteThanks a lot with this cool implementation of Struts 2. May I know does this applicable to latest OAuth2 & OIDC?
ReplyDeletePortekiz yurtdışı kargo
ReplyDeleteRomanya yurtdışı kargo
Slovakya yurtdışı kargo
Slovenya yurtdışı kargo
İngiltere yurtdışı kargo
UFBAİ
Azerbaycan yurtdışı kargo
ReplyDeleteAruba yurtdışı kargo
Avustralya yurtdışı kargo
Azor Adaları yurtdışı kargo
Bahamalar yurtdışı kargo
S4VM1Y