Author: prabath
Date: Sat Jan 5 22:03:49 2008
New Revision: 11866
Log:
OpenID Integration
Added:
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/OpenIdProvider.java
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/UserInfoServlet.java
Added:
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/OpenIdProvider.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/OpenIdProvider.java
Sat Jan 5 22:03:49 2008
@@ -0,0 +1,618 @@
+package org.wso2.solutions.identity.openid;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.wso2.solutions.identity.UserStore;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.DirectError;
+import org.openid4java.message.Message;
+import org.openid4java.message.MessageException;
+import org.openid4java.message.MessageExtension;
+import org.openid4java.message.ParameterList;
+import org.openid4java.message.ax.AxMessage;
+import org.openid4java.message.ax.FetchRequest;
+import org.openid4java.message.ax.FetchResponse;
+import org.openid4java.message.sreg.SRegMessage;
+import org.openid4java.message.sreg.SRegRequest;
+import org.openid4java.message.sreg.SRegResponse;
+import org.openid4java.server.ServerException;
+import org.openid4java.server.ServerManager;
+import org.wso2.solutions.identity.IdentityConstants;
+import org.wso2.solutions.identity.IdentityProviderConstants;
+import org.wso2.solutions.identity.IdentityProviderException;
+import org.wso2.utils.ServerConfiguration;
+
+public class OpenIdProvider {
+
+ // Instantiate a ServerManager object.
+ public static ServerManager manager = new ServerManager();
+ private String authPage;
+
+ // These are the constants used to represent attributes required by the
+ // OpenID.
+ private final static String FIRST_NAME = "firstname";
+ private final static String LAST_NAME = "lastname";
+ private final static String FULL_NAME = "fullname";
+ private final static String NICK_NAME = "nickname";
+ private final static String EMAIL = "email";
+ private final static String PHONE = "phone";
+ private final static String ADDRESS = "address";
+ private final static String CITY = "city";
+ private final static String ZIP_CODE = "zipcode";
+ private final static String COUNTRY = "country";
+ private final static String BLOG = "blog";
+
+ /**
+ * Configure the OpenID Provider's end-point URL.
+ */
+ static {
+
+ ServerConfiguration serverConfig = null;
+ String host = null;
+ String httpsPort = null;
+ String odpAddress = null;
+
+ serverConfig = ServerConfiguration.getInstance();
+ host = serverConfig.getFirstProperty("HostName");
+ httpsPort = serverConfig.getFirstProperty("Ports.HTTPS");
+
+ // This is the OpenID provider server url, right now on https - also
can
+ // be on http.
+ odpAddress = "https://" + host + ":" + httpsPort + "/admin/server/";
+ manager.setOPEndpointUrl(odpAddress);
+ }
+
+ /**
+ *
+ * @param httpReq
+ * HttpServletRequest
+ * @param httpResp
+ * HttpServletResponse
+ * @return The Url to be redirected
+ * @throws Exception
+ */
+ public String processRequest(HttpServletRequest httpReq,
+ HttpServletResponse httpResp) throws Exception {
+
+ ParameterList request = null;
+ Message message = null;
+ String responseText = null;
+ HttpSession session = null;
+
+ session = httpReq.getSession();
+
+ if (IdentityProviderConstants.OpenId.COMPLETE
.equals(httpReq.getParameter(IdentityProviderConstants.OpenId.ACTION))) {
+ // Authentication completed.
+ request = (ParameterList)
session.getAttribute(IdentityProviderConstants.OpenId.PARAM_LIST);
+ } else {
+ // Extract the parameters from the request.
+ // Authentication not completed.
+ request = new ParameterList(httpReq.getParameterMap());
+ }
+
+ String mode = request.hasParameter(IdentityConstants.OpenId.MODE) ?
request
+ .getParameterValue(IdentityConstants.OpenId.MODE)
+ : null;
+
+ if (IdentityConstants.OpenId.ASSOCIATE.equals(mode)) {
+ // Process an association request made by RP.
+ message = manager.associationResponse(request);
+ responseText = message.keyValueFormEncoding();
+ } else if (IdentityConstants.OpenId.CHECKID_SETUP.equals(mode)
+ || IdentityConstants.OpenId.CHECKID_IMMEDIATE.equals(mode)) {
+
+ boolean authenticatedAndApproved = false;
+ String userSelectedClaimedId = null;
+ String openId = null;
+
+ openId = request.hasParameter(IdentityConstants.OpenId.IDENTITY) ?
request
+ .getParameterValue(IdentityConstants.OpenId.IDENTITY)
+ : null;
+
+ // Authenticate the user.
+ authenticatedAndApproved = doLogin(getNickName(openId), httpReq
+ .getParameter(IdentityProviderConstants.OpenId.PASSWORD));
+
+ if (!authenticatedAndApproved) {
+ // Not authenticated, redirect to the authentication page.
+
session.setAttribute(IdentityProviderConstants.OpenId.PARAM_LIST, request);
+ httpResp.sendRedirect(authPage);
+ }
+
+ // Process an authentication request.
+ AuthRequest authReq = AuthRequest.createAuthRequest(request,
+ manager.getRealmVerifier());
+
+ String opLocalId = null;
+
+ message = manager.authResponse(request, opLocalId,
+ userSelectedClaimedId, authenticatedAndApproved);
+
+ if (message instanceof DirectError)
+ return directResponse(httpResp,
message.keyValueFormEncoding());
+ else {
+ if (authReq.hasExtension(AxMessage.OPENID_NS_AX)) {
+
+ MessageExtension extensions = authReq
+ .getExtension(AxMessage.OPENID_NS_AX);
+
+ if (extensions instanceof FetchRequest) {
+
+ Map required = null;
+ Map userDataExt = null;
+ FetchRequest fetchReq = null;
+ FetchResponse fetchResp = null;
+
+ fetchReq = (FetchRequest) extensions;
+ required = fetchReq.getAttributes(true);
+ userDataExt = new HashMap();
+
+ fetchResp = FetchResponse.createFetchResponse(fetchReq,
+ userDataExt);
+ setAttributeAxchange(fetchResp, required,
+ getUserData(openId));
+ message.addExtension(fetchResp);
+
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+ if (authReq.hasExtension(SRegMessage.OPENID_NS_SREG)) {
+
+ MessageExtension extension = authReq
+ .getExtension(SRegMessage.OPENID_NS_SREG);
+
+ if (extension instanceof SRegRequest) {
+
+ SRegRequest sregReq = null;
+ List required = null;
+ Map userDataSReg = null;
+ SRegResponse response = null;
+
+ sregReq = (SRegRequest) extension;
+ required = sregReq.getAttributes(true);
+
+ userDataSReg = new HashMap();
+ response = SRegResponse.createSRegResponse(sregReq,
+ userDataSReg);
+
+ setAttributeAxchange(response, required,
+ getUserData(openId));
+
+ message.addExtension(response);
+
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ return message.getDestinationUrl(true);
+ }
+ } else if (IdentityConstants.OpenId.CHECK_AUTHENTICATION.equals(mode))
{
+ // Processing a verification request.
+ message = manager.verify(request);
+ responseText = message.keyValueFormEncoding();
+ } else {
+ // Error response.
+ message = DirectError.createDirectError("Unknown request");
+ responseText = message.keyValueFormEncoding();
+ }
+
+ // Return the result to the user.
+ return responseText;
+ }
+
+ /**
+ *
+ * @param response
+ * @param required
+ * @param claimValues
+ * @throws MessageException
+ */
+ private void setAttributeAxchange(SRegResponse response, List required,
+ Map<String, String> claimValues) throws MessageException {
+
+ // If we can't find the required values with us, we simply add a null
value it.
+ // Caller should verify whether he has got non-null values to all
required attributes.
+ // If not, what to do is up to the caller.
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.EMAIL)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.EMAIL,
+ claimValues.get(EMAIL));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.NICK_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.NICK_NAME, claimValues
+ .get(NICK_NAME));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.FULL_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.FULL_NAME, claimValues
+ .get(FULL_NAME));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.LAST_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.LAST_NAME, claimValues
+ .get(LAST_NAME));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.FIRST_NAME))
{
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.FIRST_NAME, claimValues
+ .get(FIRST_NAME));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.ADDRESS)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.ADDRESS,
+ claimValues.get(ADDRESS));
+ }
+ if (required.contains(IdentityConstants.OpenId.Attributes.CITY)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.CITY,
+ claimValues.get(CITY));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.BLOG)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.BLOG,
+ claimValues.get(BLOG));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.COUNTRY)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.COUNTRY,
+ claimValues.get(COUNTRY));
+ }
+ if (required.contains(IdentityConstants.OpenId.Attributes.PHONE)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.PHONE,
+ claimValues.get(PHONE));
+ }
+
+ if (required.contains(IdentityConstants.OpenId.Attributes.ZIP_CODE)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.ZIP_CODE,
+ claimValues.get(ZIP_CODE));
+ }
+ }
+
+ /**
+ *
+ * @param response
+ * @param required
+ * @param claimValues
+ * @throws MessageException
+ */
+ private void setAttributeAxchange(FetchResponse response, Map required,
+ Map<String, String> claimValues) throws MessageException {
+
+ // If we can't find the required values with us, we simply add a null
value it.
+ // Caller should verify whether he has got non-null values to all
required attributes.
+ // If not, what to do is up to the caller..
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.EMAIL)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.EMAIL,
+ IdentityConstants.OpenId.Attributes.EMAIL_NS, claimValues
+ .get(EMAIL));
+ }
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.ADDRESS))
{
+ response.addAttribute(IdentityConstants.OpenId.Attributes.ADDRESS,
+ IdentityConstants.OpenId.Attributes.ADDRESS_NS, claimValues
+ .get(ADDRESS));
+ }
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.CITY)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.CITY,
+ IdentityConstants.OpenId.Attributes.CITY_NS, claimValues
+ .get(CITY));
+ }
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.COUNTRY))
{
+ response.addAttribute(IdentityConstants.OpenId.Attributes.COUNTRY,
+ IdentityConstants.OpenId.Attributes.COUNTRY_NS, claimValues
+ .get(COUNTRY));
+ }
+
+ if (required
+ .containsKey(IdentityConstants.OpenId.Attributes.FIRST_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.FIRST_NAME,
+ IdentityConstants.OpenId.Attributes.FIRST_NAME_NS,
+ claimValues.get(FIRST_NAME));
+ }
+
+ if
(required.containsKey(IdentityConstants.OpenId.Attributes.LAST_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.LAST_NAME,
+ IdentityConstants.OpenId.Attributes.LAST_NAME_NS,
+ claimValues.get(LAST_NAME));
+ }
+
+ if
(required.containsKey(IdentityConstants.OpenId.Attributes.FULL_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.FULL_NAME,
+ IdentityConstants.OpenId.Attributes.FULL_NAME_NS,
+ claimValues.get(FULL_NAME));
+ }
+
+ if
(required.containsKey(IdentityConstants.OpenId.Attributes.NICK_NAME)) {
+ response.addAttribute(
+ IdentityConstants.OpenId.Attributes.NICK_NAME,
+ IdentityConstants.OpenId.Attributes.NICK_NAME_NS,
+ claimValues.get(NICK_NAME));
+ }
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.PHONE)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.PHONE,
+ IdentityConstants.OpenId.Attributes.PHONE_NS, claimValues
+ .get(PHONE));
+ }
+
+ if
(required.containsKey(IdentityConstants.OpenId.Attributes.ZIP_CODE)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.ZIP_CODE,
+ IdentityConstants.OpenId.Attributes.ZIP_CODE_NS,
+ claimValues.get(ZIP_CODE));
+ }
+
+ if (required.containsKey(IdentityConstants.OpenId.Attributes.BLOG)) {
+ response.addAttribute(IdentityConstants.OpenId.Attributes.BLOG,
+ IdentityConstants.OpenId.Attributes.BLOG, claimValues
+ .get(BLOG));
+ }
+
+ }
+
+ /**
+ *
+ * @return
+ * @throws ServerException
+ * @throws IdentityProviderException
+ */
+ private String getNickName(String openId) throws ServerException,
+ IdentityProviderException {
+
+ UserStore userStore = null;
+ List users = null;
+
+ userStore = UserStore.getInstance();
+ users = userStore.getAllUserNames();
+
+ if (users == null)
+ throw new IdentityProviderException("No users found");
+
+ Map mapValues = null;
+ Iterator iterator = null;
+
+ iterator = users.iterator();
+
+ while (iterator.hasNext()) {
+
+ String user = (String) iterator.next();
+ mapValues = userStore.getClaimValues(user, null);
+
+ if (mapValues != null) {
+
+ // User has defined claims!
+ String claimId = (String) mapValues
+ .get(IdentityConstants.CLAIM_OPENID);
+
+ if (mapValues != null && !mapValues.isEmpty()) {
+ if (openId.indexOf(claimId) >= 0
+ && openId.endsWith(claimId.substring(claimId
+ .length() - 1))) {
+ return user;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param openId
+ * @return
+ * @throws ServerException
+ * @throws IdentityProviderException
+ */
+ private Map<String, String> getUserData(String openId)
+ throws ServerException, IdentityProviderException {
+
+ Map<String, String> claimValues = null;
+ UserStore userStore = null;
+ List claimList = null;
+ List users = null;
+ Map mapValues = null;
+
+ claimValues = new HashMap<String, String>();
+
+ userStore = UserStore.getInstance();
+ users = userStore.getAllUserNames();
+
+ if (users == null)
+ throw new IdentityProviderException("No users found");
+
+ Iterator iterator = users.iterator();
+
+ while (iterator.hasNext()) {
+
+ String user = (String) iterator.next();
+ mapValues = userStore.getClaimValues(user, null);
+
+ if (mapValues != null) {
+
+ // User has defined claims!
+ String claimId = (String) mapValues
+ .get(IdentityConstants.CLAIM_OPENID);
+
+ if (mapValues != null && !mapValues.isEmpty()) {
+ if (openId.indexOf(claimId) >= 0
+ && openId.endsWith(claimId.substring(claimId
+ .length() - 1))) {
+
+ // first name
+ if (mapValues
+
.containsKey(IdentityConstants.CLAIM_GIVEN_NAME))
+ claimValues.put(FIRST_NAME, (String) mapValues
+ .get(IdentityConstants.CLAIM_GIVEN_NAME));
+ else
+ claimValues.put(FIRST_NAME, null);
+
+ // last name
+ if (mapValues
+ .containsKey(IdentityConstants.CLAIM_SURNAME))
+ claimValues.put(LAST_NAME, (String) mapValues
+ .get(IdentityConstants.CLAIM_SURNAME));
+ else
+ claimValues.put(LAST_NAME, null);
+
+ // full name
+ if (claimValues
+
.containsKey(IdentityConstants.CLAIM_GIVEN_NAME)
+ && claimValues
+
.containsKey(IdentityConstants.CLAIM_SURNAME))
+ claimValues
+ .put(
+ FULL_NAME,
+ (String) mapValues
+
.get(IdentityConstants.CLAIM_GIVEN_NAME)
+ + " "
+ + (String) mapValues
+
.get(IdentityConstants.CLAIM_SURNAME));
+ else if (claimValues
+
.containsKey(IdentityConstants.CLAIM_GIVEN_NAME)
+ && !claimValues
+
.containsKey(IdentityConstants.CLAIM_SURNAME))
+ claimValues.put(FULL_NAME, (String) mapValues
+ .get(IdentityConstants.CLAIM_GIVEN_NAME));
+ else if (!claimValues
+
.containsKey(IdentityConstants.CLAIM_GIVEN_NAME)
+ && claimValues
+
.containsKey(IdentityConstants.CLAIM_SURNAME))
+ claimValues.put(FULL_NAME, (String) mapValues
+ .get(IdentityConstants.CLAIM_SURNAME));
+ else
+ claimValues.put(FULL_NAME, null);
+
+ // nick name
+ claimValues.put(NICK_NAME, user);
+
+ // email address
+ if (claimValues
+
.containsKey(IdentityConstants.CLAIM_EMAIL_ADDRESS))
+ claimValues
+ .put(
+ EMAIL,
+ (String) mapValues
+
.get(IdentityConstants.CLAIM_EMAIL_ADDRESS));
+ else
+ claimValues.put(EMAIL, null);
+
+ // phone
+ if (claimValues
+
.containsKey(IdentityConstants.CLAIM_HOME_PHONE))
+ claimValues.put(PHONE, (String) mapValues
+ .get(IdentityConstants.CLAIM_HOME_PHONE));
+ else
+ claimValues.put(PHONE, null);
+
+ // address
+ if (claimValues
+
.containsKey(IdentityConstants.CLAIM_STREET_ADDRESS))
+ claimValues
+ .put(
+ ADDRESS,
+ (String) mapValues
+
.get(IdentityConstants.CLAIM_STREET_ADDRESS));
+ else
+ claimValues.put(ADDRESS, null);
+
+ // city
+ if (claimValues
+ .containsKey(IdentityConstants.CLAIM_CITY))
+ claimValues.put(CITY, (String) mapValues
+ .get(IdentityConstants.CLAIM_CITY));
+ else
+ claimValues.put(CITY, null);
+
+ // zipcode
+ if (claimValues
+
.containsKey(IdentityConstants.CLAIM_POSTAL_CODE))
+ claimValues.put(ZIP_CODE, (String) mapValues
+ .get(IdentityConstants.CLAIM_POSTAL_CODE));
+ else
+ claimValues.put(ZIP_CODE, null);
+
+ // country
+ if (claimValues
+ .containsKey(IdentityConstants.CLAIM_COUNTRY))
+ claimValues.put(COUNTRY, (String) mapValues
+ .get(IdentityConstants.CLAIM_COUNTRY));
+ else
+ claimValues.put(COUNTRY, null);
+
+ // blog - currently we don't have a claim for this
+ claimValues.put(BLOG, null);
+
+ break;
+ }
+ }
+ }
+ }
+
+ return claimValues;
+ }
+
+ /**
+ *
+ * @param username
+ * @param password
+ * @return
+ */
+ private boolean doLogin(String username, String password) {
+ try {
+ UserStore userStore = UserStore.getInstance();
+ return userStore.authenticate(username, password);
+ } catch (Exception e) {
+ return false;
+ }
+
+ }
+
+ /**
+ *
+ * @param httpResp
+ * @param response
+ * @return
+ * @throws IOException
+ */
+ private String directResponse(HttpServletResponse httpResp, String
response)
+ throws IOException {
+ ServletOutputStream stream = null;
+ try {
+ stream = httpResp.getOutputStream();
+ stream.write(response.getBytes());
+ } finally {
+ if (stream != null)
+ stream.close();
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param authPage
+ */
+ public void setAuthPage(String authPage) {
+ this.authPage = authPage;
+ }
+
+}
\ No newline at end of file
Added:
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/UserInfoServlet.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/identity-provider/src/main/java/org/wso2/solutions/identity/openid/UserInfoServlet.java
Sat Jan 5 22:03:49 2008
@@ -0,0 +1,46 @@
+package org.wso2.solutions.identity.openid;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class UserInfoServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -2306630174647697559L;
+
+ /**
+ *
+ */
+ protected void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String serverUrl = "http://" + req.getServerName() + ":"
+ + req.getServerPort() + "/server";
+ String back = "";
+ if ("html".equals(req.getParameter("format"))) {
+ resp.setContentType("text/html");
+ back = "<html><head>\n" + "<link rel='openid.server' href='"
+ + serverUrl + "'/>\n"
+ + "</head><body>in html</body></html>";
+ } else {
+ resp.setContentType("application/xrds+xml");
+ back = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xrds:XRDS\n" + " xmlns:xrds=\"xri://$xrds\"\n"
+ + " xmlns:openid=\"http://openid.net/xmlns/1.0\"\n"
+ + " xmlns=\"xri://$xrd*($v*2.0)\">\n" + " <XRD>\n"
+ + " <Service priority=\"0\">\n"
+ + " <Type>http://openid.net/signon/1.0</Type>\n"
+ + " <URI>http://" + req.getServerName() + ":"
+ + req.getServerPort() + "/server</URI>\n"
+ + " </Service>\n" + " </XRD>\n" + "</xrds:XRDS>";
+ }
+
+ PrintWriter out = resp.getWriter();
+ out.write(back);
+ }
+
+}
_______________________________________________
Identity-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/identity-dev