Hacking JSecurity plugin to supports OpenId


I'm currently developing an application for my new brand company and I'd like that supports authentication with username and password , and OpenId.

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)  
 }

}
Now I have to hack AuthController to manage openid issues. The trick is when a user try to signIn, if I recive an OpenId identifier from OpenId Plugin then I put it in OpenIdContextHolder.
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...
// ...
}
Next step is update JsecDbRealm generated. I have to retrieve OpenId identifier from ContextHolder, and lookup in my domain objects. I use the trick to register my openId users in JScecurity with the password 'secret' but if anyone try to access with username and password in this kind of users, I throw an Exception.
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...
// ...
The last step is redirect, openid users to signIn controller after logged (you only have to change it in OpenId Plugin).

And that's all folks.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值