I could install Acegi Grails Plugin, but I'm very happy using JSecurity, ok no problem let's hack.
First, I have to install OpenId Plugin to support OpenId authenticantion, with this plugin I can manage login process and get openid identifier for OpenId users.
With JSecurity installed and done QuickStart, I need to pass Openid identifier in auth process, for this I've created class OpenIdContextHolder to save in a ThreadLocal context.
class OpenIdContextHolder{
private static final ThreadLocal openIdContextHolder = new ThreadLocal();
static void resetContext() {
openIdContextHolder.set(null);
}
static def getOpenIdIdentifier(){
openIdContextHolder.get()
}
static void setOpenIdIdentifier(id){
openIdContextHolder.set(id)
}
}
def login = {
if(openidService.isLoggedIn(session)){
return redirect(action:'signIn')
}
return [ username: params.username, rememberMe: (params.rememberMe != null), targetUri: params.targetUri ]
}
def signIn = {
// if is logged with openid set contextholder
if(openidService.isLoggedIn(session)){
def openId = openidService.getIdentifier(session)
OpenIdContextHolder.setOpenIdIdentifier(openId)
params.rememberMe = true
params.username = openId
params.password = "nullpass"
}
def authToken = new UsernamePasswordToken(params.username, params.password)
// continues the default generated code...
// ...
}
def authenticate(authToken) {
log.info "Attempting to authenticate ${authToken.username} in DB realm..."
// experimental!!
def openid = OpenIdContextHolder.getOpenIdIdentifier()
OpenIdContextHolder.resetContext()
log.info "OpenIdContextHolder request with openid: ${openid}"
if(openid){
def openidUser = User.findByOpenid(openid)
if (!openidUser)
throw new UnknownAccountException("No account found for user [${username}]")
log.info "Jsecurity with Openid ${openidUser.username} : ${openidUser.openid}"
authToken.password = 'secret'
authToken.username = openidUser.username
}else {
def openidUser = User.findByUsername(authToken.username)
if(openidUser?.openid?.trim()){
// trying to access with password for openid user
log.info "Jsecurity: Trying to access with password for user: ${openidUser.username} : ${openidUser.openid}"
throw new IncorrectCredentialsException("Invalid password for openid user '${authToken.username}', try to use openid instead user:password")
}
}
def username = authToken.username
// continues the default generated code...
// ...
And that's all folks.
2 comments:
Thanks for the post.
I followed the steps and managed to get JSecurity working with Facebook Connect.
Hi, thanks for this solution.
Could you please detail the last step for the facebook-connect case:
redirect user to sigbnIn after loggin in?
Thank you very much.
Francis
Post a Comment