Created
October 15, 2009 10:46
-
-
Save ArtemGr/210885 to your computer and use it in GitHub Desktop.
OpenID login example; GAE and dyuproject.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package grond.actions | |
import javax.servlet.http.HttpServletRequest | |
import com.dyuproject.openid.{RelyingParty, OpenIdUser} | |
import com.dyuproject.openid.ext.{SRegExtension, AxSchemaExtension} | |
import com.dyuproject.util.http.UrlEncodedParameterMap | |
import grond.UserException, grond.model._ | |
/** Perform the OpenID login using the identifier submitted in "openid_identifier".<br> | |
* If login was successfull, then openidLogin.getAuthenticatedUser will start returning | |
* the user currently logged in. */ | |
class openidLogin extends ActionHandler { | |
var errorMessage: String = null | |
override def invoke (context: java.util.HashMap[String, Object], api: GrondAPI, pathInfo: String): String = try { | |
val request = api.getRequest; val response = api.getResponse | |
import openidLogin._ | |
/* Missing Javadoc, see: http://code.google.com/p/dyuproject/issues/detail?id=14 | |
* Return the current user, | |
* either an already authenticated one, | |
* or the one just discovered from the | |
* <i>openid.identifier.parameter<i> | |
* (= "openid_identifier" by default).<br> | |
* Returns <code>null</code> if the {@link Constants.OPENID_MODE} associated | |
* with the request is set to {@link Constants.Mode.CANCEL} | |
* (in order to login under a different id), | |
* or if the authentification is timed out. | |
* If returned user is <code>null</code> | |
* and {@link isAuthResponse} is <code>true</code> | |
* then we have an authentification timeout. */ | |
val user = relyingParty.discover (request) // Step 0: Get user instance. | |
if (user eq null) { | |
errorMessage = "Timeout or logout." | |
return pathInfo | |
} | |
// Step 3: User is authenticated successfully. (Noop and never happens here). | |
if (user.isAuthenticated) { | |
return pathInfo | |
} | |
// Step 2: Get authentification response from OpenID provider. | |
if (user.isAssociated && RelyingParty.isAuthResponse (request)) { | |
if (relyingParty.verifyAuth (user, request, response)) { | |
println ("openidLogin: User verified! Removing GET parameters from the URL.") | |
response.sendRedirect(request.getRequestURI) | |
return pathInfo | |
} else { | |
errorMessage = "User verification failed!" | |
return pathInfo | |
} | |
} | |
// Step 1: Associate and authenticate user. (Locates OpenID provider and sends user there). | |
val url = request.getRequestURL | |
val trustRoot = url.substring (0, url.indexOf ("/", 9)) | |
val realm = url.substring (0, url.lastIndexOf("/")) | |
val returnTo = url.toString + "?1=openidLogin" | |
if (relyingParty.associateAndAuthenticate(user, request, response, trustRoot, realm, returnTo)) { | |
println ("openidLogin: User is associated and then redirected to his openid provider for authentication.") | |
assert (response.isCommitted) | |
return pathInfo | |
} | |
pathInfo | |
} catch {case UserException (msg, _) => errorMessage = "Error: " + msg; pathInfo} | |
} | |
object openidLogin { | |
/** Returns the user currently logged in via OpenID.<br> | |
* (The user instance is cached in the request). */ | |
def getAuthenticatedUser (request: HttpServletRequest): OpenIdUser = { | |
val user = relyingParty.discover (request) | |
if ((user ne null) && user.isAuthenticated) user else null | |
} | |
val relyingParty = RelyingParty.getInstance | |
relyingParty.addListener (new SRegExtension () .addExchange ("email")) | |
relyingParty.addListener (new AxSchemaExtension () .addExchange ("email")) | |
relyingParty.addListener (new RelyingParty.Listener { | |
override def onDiscovery (user: OpenIdUser, request: HttpServletRequest): Unit = {} | |
override def onPreAuthenticate (user: OpenIdUser, request: HttpServletRequest, params: UrlEncodedParameterMap): Unit = {} | |
override def onAuthenticate (user: OpenIdUser, request: HttpServletRequest): Unit = { | |
val sreg = SRegExtension.remove (user) | |
val axschema = AxSchemaExtension.remove (user) | |
if ((sreg ne null) && !sreg.isEmpty) { | |
println ("openidLogin: got SRegExtension: " + sreg) | |
user.setAttribute ("info", sreg) | |
} else if ((axschema ne null) && !axschema.isEmpty) { | |
println ("openidLogin: got AxSchemaExtension: " + axschema) | |
user.setAttribute ("info", axschema) | |
} | |
} | |
override def onAccess (user: OpenIdUser, request: HttpServletRequest): Unit = {} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment