Spring security 3 在使用 OpenID 进行身份验证时忽略禁用/锁定标志

Posted

技术标签:

【中文标题】Spring security 3 在使用 OpenID 进行身份验证时忽略禁用/锁定标志【英文标题】:Spring security 3 ignoring disabled/locked flags when authenticating with OpenID 【发布时间】:2012-09-01 07:12:21 【问题描述】:

我正在开发一个使用 Spring Security 3.0.7 通过用户名/密码或使用 OpenID 对用户进行身份验证的 Web 应用程序。现在我需要能够禁用某些帐户。起初我找不到相关文档,但最后我发现了User.isEnabled():

指示用户是启用还是禁用。无法验证禁用的用户。

这个标志的值在构造函数中给出。

使用表单进行身份验证时,它似乎工作正常。不幸的是,Spring 的 OpenID 似乎完全忽略了该标志。我尽可能多地登录,我可以在日志中看到:

调试 o.s.s.o.OpenIDAuthenticationFilter - 身份验证成功。 更新 SecurityContextHolder 以包含:[org.springframework.security.openid.OpenIDAuthenticationToken@66348da1:主体:mypackage.UserInfo@ddd49b1b:用户名:cbada36792e42a3be5a5e0f77d14e918186c7e3f;密码保护]; 启用:假; AccountNonExpired:真;凭据非过期:真; AccountNonLocked:真;授予权限:ROLE_USER;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a:RemoteIpAddress:127.0.0.1;会话 ID:1arhd8er0sj1yynglq8linpnb;授予权限:ROLE_USER,属性:[]]

如何在禁用的帐户上成功验证?(如果我尝试锁定帐户,则相同。)

我错过了什么重要的东西吗?或者它只是一个错误?有什么想法要寻找什么,还有什么要启用的日志记录?


我的 XML 配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
  xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.0.xsd">

  <global-method-security secured-annotations="enabled">
  </global-method-security>

  <http use-expressions="true" auto-config="true">
    <intercept-url pattern="/" access="permitAll" />
    <!-- ... other pattens -->
    <form-login
        login-page="/"
        authentication-success-handler-ref="loginSuccessHandler"
    />

    <remember-me data-source-ref="dataSource" user-service-ref="myUserDetails"/>

    <openid-login
        user-service-ref="openIdAuth"
        authentication-success-handler-ref="loginSuccessHandler"
        authentication-failure-handler-ref="openIdFailureHandler"
        >
      <attribute-exchange>
        <openid-attribute name="email" type="http://axschema.org/contact/email" required="true" />
        <openid-attribute name="name" type="http://axschema.org/namePerson" />
      </attribute-exchange>
    </openid-login>
    <logout success-handler-ref="logoutSuccessHandler"/>
  </http>

  <authentication-manager>
    <authentication-provider ref="daoAuthenticationProvider"/>
  </authentication-manager>

  <beans:bean id="daoAuthenticationProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <beans:property name="userDetailsService" ref="myUserDetails"/>
    <beans:property name="saltSource" ref="saltSource"/>
    <beans:property name="passwordEncoder" ref="passwordEncoder"/>
    <beans:property name="preAuthenticationChecks">
      <beans:bean class="org.springframework.security.authentication.AccountStatusUserDetailsChecker"/>
    </beans:property>
  </beans:bean>
</beans:beans>

这里的myUserDetails 是我的自定义bean,它从数据库加载用户并返回User 的简单自定义实现:

public class UserInfo
    extends User

    public UserInfo(UserEntity user)
    
        super(  user.getUserName(),
                user.getPassword(),
                !user.isDisabled(), // enabled
                true, // non-expired
                true, // credentials non-expired
                !user.isLocked(), // non-locked
                UserInfo.authorities(user) // my static method
            );
        // store some info for further reference here
        // ...
    
    // ...

【问题讨论】:

【参考方案1】:

我现在正在处理类似的情况。

Spring Security 基于过滤器链。如果您声明 openid 比 opendId 身份验证添加到您的安全过滤器链(我不知道 spring openid 详细信息)。

当您的过滤器链处于 openId 步骤并且有人已登录时,它将返回身份验证成功,而无需查看 UserDetails 表中的禁用状态。

第 7.3 章:docs.spring.io/spring-security/site/docs/3.0.x/reference/security-filter-chain.html

当有人通过 FB 登录时,我使用 Spring Social(用于 FB 等)并且 isDisabled() 也不适用于我。

解决方案是用你的更改默认 spring 的 openid 实现,在 UserDetails 中监视 isDisabled()。

可能 这里:OpenIDAuthenticationProvider。这是一枪!我不知道spring openid

希望对您有所帮助。

【讨论】:

以上是关于Spring security 3 在使用 OpenID 进行身份验证时忽略禁用/锁定标志的主要内容,如果未能解决你的问题,请参考以下文章

Grails 使用 spring-security-core-3.0.6+ 重定向注销后

在 Grails 中使用 Pre/Post Spring-Security Annotations

如何在 Spring Security 3 和 Spring EL 中使用角色层次结构?

如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config

使用spring 3 security在jsp页面中访问我的自定义用户对象

Spring Security 3.2:不考虑@Secured注解