grails - 在 Spring Security 中自定义身份验证

标签 grails spring-security grails-plugin

在我的 Grails 应用程序中,我使用 Spring Security 插件并定义了 custom userDetailsService Spring bean为了控制如何检索用户和角色数据,例如

class MyUserDetailsService implements GrailsUserDetailsService {

    /**
     * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
     * we give a user with no granted roles this one which gets past that restriction but
     * doesn't grant anything.
     */
    static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

    UserDetails loadUserByUsername(String username, boolean loadRoles) {
        return loadUserByUsername(username)
    }

    UserDetails loadUserByUsername(String username) {
        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 CustomUserDetails(
                    user.username,
                    user.password,
                    user.enabled,
                    !user.accountExpired,
                    !user.passwordExpired,
                    !user.accountLocked,
                    authorities ?: NO_ROLES,
                    user.id,
                    user.name)
        }
    }
}

上面引用的 CustomUserDetails 类只是使用 name 字段扩展 GrailsUser:

class CustomUserDetails extends GrailsUser {

    private static final long serialVersionUID = 1;

    final String name

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

        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id)
        this.name = displayName
    }
}

除了自定义用户和角色数据的检索方式之外,我还想控制用户的身份验证方式。就我而言,身份验证过程并不像通常的“检查输入的密码是否与数据库中的密码匹配”那么简单。用户身份验证的实际细节并不相关,因此为了简单起见,我们假设如果用户的 name 字段与输入的密码匹配,则他被授予封装在 中的角色(权限) >自定义用户详细信息

我猜想插件中的某处有一个 Spring bean,我可以覆盖它以自定义默认身份验证机制,但是是哪一个呢?由于 name 字段仅由 CustomUserDetails 定义,因此我需要访问 MyUserDetailsS​​ervice 返回的此类实例才能执行自定义身份验证,这可能吗?

最佳答案

我在这里讨论了自定义登录,示例应用程序的代码为:http://burtbeckwith.com/blog/?p=1090

但是,如果您只想向用户授予与数据库中不同的角色,我会在 MyUserDetailsS​​ervice 中执行此操作。不要求角色位于数据库中 - Spring Security 只需要一堆 GrantedAuthorityImpl 实例。在我开发的一款应用中,我在身份验证期间自动将 ROLE_USER 授予常规网站用户,以避免浪费数据库空间。

编辑:

如果您使用 DaoAuthenticationProvider,则可以通过自定义 preAuthenticationChecks 和/或 postAuthenticationChecks bean 在身份验证期间添加其他检查。将插件中的子类化并添加您自己的检查,并将它们在 resources.groovy 中注册为

preAuthenticationChecks(MyPreAuthenticationChecks)
postAuthenticationChecks(MyPostAuthenticationChecks)

关于grails - 在 Spring Security 中自定义身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20751344/

相关文章:

java - 替换 SESSION_MANAGEMENT_FILTER 位置的默认过滤器

Grails Release 插件未在远程 maven 存储库上部署插件

hibernate - 将字符串列转换为 Long grails createCriteria

java - Spring Security 使用 jwt 获取所有用户登录

grails - Grails服务未在jaxrs资源类内自动接线

java - 为什么 Spring Security 在所有表单帖子上总是响应 403 Forbidden?

Grails Jquery-ui 插件配置

grails - 如何在Grails中记录所有CRUD操作?

grails - 将参数化的SQL转换为HQL的问题

pdf - 使用ByteArrayOutputStream使用iText将水印添加到pdf