GrailsSpring安全性扩展用户属性

GrailsSpring安全性扩展用户属性,grails,spring-security,Grails,Spring Security,我有一个项目,将是一个附加到现有的ERP应用程序。我已经使用基本的Spring安全设置使SSO正常工作(请参阅我的问题:)。另外,我没有使用s2快速启动 我对Java开发还是新手,所以请耐心听我说……我一直在浏览文档和示例,在某些方面,我对我所看到的更为困惑。我有几个问题: 1) 此设置允许我访问登录用户的用户名,但不允许访问其他内容?如何访问用户对象以访问这些属性?现在,我正在使用: def userDetails = springSecurityService.principal then:

我有一个项目,将是一个附加到现有的ERP应用程序。我已经使用基本的Spring安全设置使SSO正常工作(请参阅我的问题:)。另外,我没有使用s2快速启动

我对Java开发还是新手,所以请耐心听我说……我一直在浏览文档和示例,在某些方面,我对我所看到的更为困惑。我有几个问题:

1) 此设置允许我访问登录用户的用户名,但不允许访问其他内容?如何访问用户对象以访问这些属性?现在,我正在使用:

def userDetails = springSecurityService.principal
then: userDetails ?.getUsername() to get the username
and: userDetails ?.getAuthorities() to get roles
除了这是访问这些属性的最佳方式之外,这一切都正常工作? i、 例如,userdetails中是否有其他属性,以及如何访问这些属性

也许这个问题的答案取决于我下一步该怎么做

2) 我正在使用CAS进行身份验证,但现在我想从LDAP中提取一些附加属性。我曾经尝试过创建这样的自定义UserDetailsService,但即使在我通过了初始编译错误之后,它似乎仍然需要User domain类。如果我想用附加值扩展UserDetails,我必须实现用户域类吗

在我的例子中,我真的只需要一个LDAP属性——而这一切似乎需要很多提升才能实现。我看了又看,但找不到一个很好的工作/简单的例子来做这件事…很多人都涉及Gorm或安装了s2 quickstart

蒂亚

豆子

更新 这是我的配置…请参见结尾处的错误:

Config.groovy snip CustomUserDetails.groovy User.groovy(域类)
类用户{
临时安全服务
字符串用户名
字符串密码
字符串邮件
//字符串显示名
布尔启用
布尔帐户已过期
布尔帐户锁定
布尔密码过期
静态约束={
用户名空白:false,唯一:true
密码空白:false
}
静态映射={
密码列:“`password`”
}
设置getAuthorities(){
UserRole.findallbyser(this.collect{it.role}作为集合
}
def beforeInsert(){
encodePassword()
}
def beforeUpdate(){
if(isDirty(‘密码’)){
encodePassword()
}
}
受保护的无效密码(){
password=springSecurityService.encodePassword(密码)
}
}
我收到错误信息

2014-02-18 08:37:48106[http-apr-8444-exec-9]错误。GrailExceptionResolver-在处理请求[GET]/basecas_04/protected/list时发生MissingPropertyException 类:org.springframework.security.ldap.userdetails.ldapuserdetailsiml没有这样的属性:id 可能的解决方案:dn。跟踪如下: groovy.lang.MissingPropertyException:没有此类属性:类的id:org.springframework.security.ldap.userdetails.LdapUserDetailsImpl 可能的解决方案:dn 位于grails.plugins.springsecurity.SpringSecurityService.getCurrentUser(SpringSecurityService.groovy:80) 在basecas_04.ProtectedController.list(ProtectedController.groovy:22) 位于grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195) 位于grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63) 位于org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:65) 位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 运行(Thread.java:722)

对此有何想法:


没有这样的属性:class:org.springframework.security.ldap.userdetails.ldapuserdetailsiml的id

您的答案可能在这里:spring security ldap(如果您正在使用它,因为我相信这也是您正在使用的东西):-t

正在快速搜索:

security.ldap.userdetails.LdapUserDetailsManager

返回:

loadUserByUsername

公共用户详细信息loadUserByUsername(字符串用户名) 抛出UsernameNotFoundException, DataAccessException

从接口复制的说明:UserDetailsService 根据用户名查找用户。在实际实现中,搜索可能不区分大小写,也可能不区分大小写,具体取决于实现实例的配置方式。在这种情况下,返回的UserDetails对象的用户名可能与实际请求的用户名不同

Specified by:
    loadUserByUsername in interface UserDetailsService

Parameters:
    username - the username identifying the user whose data is required. 
Returns:
    **a fully populated user record (never null)** 

在SpringSecurityBean迷宫中导航可能有点困难。好的一面是,一旦你掌握了方向,这将是一个非常强大和灵活的豆迷宫:)

  • 对于#1,您可以自由覆盖默认的
    UserDetails
    类 使用您自己的自定义实现添加任何其他 你需要的财产。为此,您需要定义一个自定义
    UserDetailsService
    如核心插件文档中所述

  • 对于#2,此链接可能有助于:


有一件事我很担心,为了扩展UserDetails,我必须有一个User域类吗?不,你不一定需要一个
User
域类。您的自定义
UserDetails服务
只需要返回符合
UserDetails
接口的对象。您可以随意定义和构造这个
UserDetails
对象(即不依赖
User
域类)。Burt Beckwith在这里提供了更多的提示:浏览一下您最近的编辑,看起来您缺少了
ldapUserDetailsService
bean。此外,您还需要在
src/groovy/
下使用自定义的
UserDetailsService
——它不是真正的Grails服务。最后,另一个可能有帮助的链接:好的,我添加了ldapuserdetails服务
// Place your Spring DSL code here
beans = {


    // load ldap roles from spring security
    initialDirContextFactory(org.springframework.security.ldap.DefaultSpringSecurityContextSource,
        "ldap://xx.xx.xx.xx:389"){
        userDn = "cn=admin,dc=mydomain,dc=com"
        password = "pw"
    }

    ldapUserSearch(org.springframework.security.ldap.search.FilterBasedLdapUserSearch,
        "ou=employees,dc=mydomain,dc=com", "uid={0}", initialDirContextFactory){

    }

    ldapAuthoritiesPopulator(org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator,
        initialDirContextFactory,"ou=groups,dc=mydomain,dc=com"){
          groupRoleAttribute = "gidNumber"
          groupSearchFilter = "memberUid={1}"
          searchSubtree = true
          rolePrefix = "ROLE_"
          convertToUpperCase = true
          ignorePartialResultException = true
    }

    ldapUserDetailsService(org.springframework.security.ldap.userdetails.LdapUserDetailsService,
    ldapUserSearch,
    ldapAuthoritiesPopulator)

    userDetailsService(basecas_04.CustomUserDetailsService)


}
package basecas_04

import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.User

class MyUserDetails extends GrailsUser {   

    final String mail   

    MyUserDetails(String username, String password, boolean enabled,
                 boolean accountNonExpired, boolean credentialsNonExpired,
                 boolean accountNonLocked,
                 Collection<GrantedAuthority> authorities,
                 long id, String mail) {

    super(username, password, enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, authorities, id)      

    this.mail = mail
   }
}
package basecas_04


import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser  import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils  import org.springframework.security.core.authority.GrantedAuthorityImpl  import org.springframework.security.core.userdetails.UserDetails  import org.springframework.security.core.userdetails.UsernameNotFoundException


import basecas_04.User

class CustomUserDetailsService implements GrailsUserDetailsService {        static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]            UserDetails loadUserByUsername(String username, boolean loadRoles)      throws UsernameNotFoundException {                  return loadUserByUsername(username)             }           UserDetails loadUserByUsername(String username)     throws UsernameNotFoundException {             
                User.withTransaction { status ->   
                                User user = User.findByUsername(username)                       if (!user)                              throw new UsernameNotFoundException('User not found', username)                 

                        def authorities = user.authorities.collect {
                new GrantedAuthorityImpl(it.authority)          }                         
                        return new MyUserDetails(user.username, user.password, user.enabled, !user.accountExpired,                 
                !user.passwordExpired, !user.accountLocked,                 
                authorities ?: NO_ROLES, user.id, user.mail)                    }           }   }
class User {

    transient springSecurityService

    String username
    String password
    String mail
    //String displayName
    boolean enabled
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    static constraints = {
        username blank: false, unique: true
        password blank: false
    }

    static mapping = {
        password column: '`password`'
    }

    Set<Role> getAuthorities() {
        UserRole.findAllByUser(this).collect { it.role } as Set
    }

    def beforeInsert() {
        encodePassword()
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            encodePassword()
        }
    }

    protected void encodePassword() {
        password = springSecurityService.encodePassword(password)
    }
}
Specified by:
    loadUserByUsername in interface UserDetailsService

Parameters:
    username - the username identifying the user whose data is required. 
Returns:
    **a fully populated user record (never null)**