简体   繁体   English

Grails,从 Acegi 升级到 Spring 安全插件

[英]Grails, upgrading from Acegi to Spring security plugin

Yesterday I started upgrading our Grails app from Acegi plugin 0.5.2 to the Spring security plugin.昨天我开始将我们的 Grails 应用程序从 Acegi 插件 0.5.2 升级到 Spring 安全插件。 I'm running into a few issues, maybe anyone can help here?我遇到了一些问题,也许有人可以在这里提供帮助?

After making the necessary changes (as documented by Burt Beckwith on Migrating from the Acegi Plugin ) I was able to start the Grails app once again (woohoo.), However.进行必要的更改后(如 Burt Beckwith 在Migrating from the Acegi Plugin 中所述),我能够再次启动 Grails 应用程序(哇哦。),但是。 logging in didn't work anymore.登录不再起作用。

Our situation is as follows: we use our Grails application pure for its application logic.我们的情况如下:我们使用我们的 Grails 应用程序纯作为其应用程序逻辑。 Authentication is done using a username and password through webservices.身份验证是通过网络服务使用用户名和密码完成的。 As backends we use the database of the app (dao) and a LDAP backend.作为后端,我们使用应用程序 (dao) 的数据库和 LDAP 后端。 For now, we've disabled LDAP, to make testing easier.目前,我们已禁用 LDAP,以简化测试。

This is the code which does the authentication:这是进行身份验证的代码:

def authenticate(String username, String password) {
try {
      println "Trying authentication with user " + username + " and password " + password + "."
      def tempToken = new UsernamePasswordAuthenticationToken(username, password)
      println "Temptoken is " + tempToken
      def token = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password))
      println "Authentication token received was: " + token
    } catch (AuthenticationException authenticationException) {
        return false
    }
    return true     
}

This prints to the log:这将打印到日志:

Trying authentication with user admin and password admin.
Temptoken is org.springframework.security.providers.UsernamePasswordAuthenticationToken@1f: Principal: admin; Password: [PROTECTED]; Authenticated: false; Details: null; Not granted any authorities

And then it all stops.然后一切都停止了。

The domain classes we use are rather straightforward.我们使用的领域类相当简单。 We do not use a class such as the User Role for the joins between people and their authorities.我们不使用 class 之类的用户角色来连接人员及其权限。 Instead we use a many-to-many mapping, as this has always worked for us and is easy to maintain.相反,我们使用多对多映射,因为这对我们一直有效并且易于维护。

Our authority domain class:我们的权限域class:

class Authority {
static hasMany = [people: Person]

/** description */
String description
/** ROLE String */
String authority = ''

String authorityType

static constraints = {
    authority(help:'x',class:'wide',blank: false,unique:true)
    description(help:'x',class:'extrawide')
    authorityType(help:'x',class:'wide')
    people(help:'x',selectSort:'username',display:false)
}   

String toString() {
      return authority;
}   
}

And our Person domain class:而我们的 Person 域 class:

class Person  {

static hasMany = [authorities: Authority]
static belongsTo = Authority

//Authority primaryGroup

/** Username */
String username
/** User Real Name*/
String userRealName
String familyName
String givenName

/** MD5 Password */
String passwd
/** enabled */
boolean enabled

String email
boolean emailShow

/** description */
String description = ''



static constraints = {
    username(blank: false, unique: true,help:'x',class:'wide')
    userRealName(blank: false,help:'x',class:'wide')
    familyName(blank: false,help:'x',class:'wide')
    givenName(blank: false,help:'x',class:'wide')
    email(help:'x',class:'wide')
    emailShow(help:'x')
    enabled(help:'x')
    passwd(blank: false,password:true,show:false,help:'x',class:'wide')
    authorities(nullable:true,help:'x',sortable:true,selectSort:'authority')        
}

String toString() {
      return username;
  }
}

In Config.Groovy, we have defined:在 Config.Groovy 中,我们定义了:

security {
active = false
cacheUsers = false

grails.plugins.springsecurity.providerNames = ['daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider']

grails.plugins.springsecurity.userLookUp.userDomainClassName = "Person"
grails.plugins.springsecurity.authority.className = "Authority"

As far as the documentation goes, this should work by all means (and so it did for the "old" Acegi setup).就文档而言,这应该无论如何都可以工作(对于“旧” Acegi 设置也是如此)。

To gather some more insights I briefly activated LDAP and found the same issue.为了收集更多信息,我短暂激活了 LDAP 并发现了同样的问题。 WireShark told me that no LDAP calls were made during the login process. WireShark 告诉我,在登录过程中没有进行 LDAP 调用。 My guess would be that either there's something wrong with the code in the Authenticate function or SpringSecurity doesn't know how to pick up our domain classes.我的猜测是,Authenticate function 中的代码有问题,或者 SpringSecurity 不知道如何获取我们的域类。

I'd be glad to read any insights!我很乐意阅读任何见解!

It seems that the token is not valid, so the authenticate() call fails and generates an exception (IIRC it only returns a value if the call succeed).似乎令牌无效,因此 authenticate() 调用失败并生成异常(IIRC 只有在调用成功时才返回一个值)。

My first try would be to check if the database has a row for user:'admin', password:'admin' for the environment.我的第一次尝试是检查数据库是否有一行用于用户:'admin',密码:'admin' 的环境。

After some thought, I would double-check the password property in Person class.经过一番思考,我会仔细检查 Person class 中的密码属性。 Either via mapping in the domain class, or better via通过在域 class 中的映射,或者更好地通过

userLookup.passwordPropertyName = "passwd"

UPDATE: Third thing to check.更新:第三件事要检查。

active = false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM