使用带有默认身份验证提供程序的Spring-Security PasswordEncoder? [英] Using Spring-Security PasswordEncoder with default authentication provider?

查看:106
本文介绍了使用带有默认身份验证提供程序的Spring-Security PasswordEncoder?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring 4.0.8 RELEASE和Spring-Security 3.2.5 RELEASE

I'm using Spring 4.0.8 RELEASE and Spring-Security 3.2.5 RELEASE

我正在使用HTTP Digest构建REST WebService,只有注册用户可以访问.

I'm building a REST WebService using HTTP Digest to which only registered users have access to.

我的web.xml是这样的:

My web.xml is this:

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param> 
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>


<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

applicationContext.xml包含我的Controller/DAO,对此很重要,仅此而已:

The applicationContext.xml contains my Controller/DAO important for this is only this:

<import resource="security-context.xml" />

<bean id="daoPersonal" class="com.test.dao.PersonalDAO">
    <property name="dataSource" ref="dataSource" />
</bean>

现在,security-context.xml看起来像这样:

Now the security-context.xml looks like this:

 <?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-4.0.xsd
         http://www.springframework.org/schema/security
         http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <debug />
    <http entry-point-ref="digestEntryPoint">
        <headers />
        <intercept-url pattern="/**" access="ROLE_USER" />
        <custom-filter ref="digestFilter" after="BASIC_AUTH_FILTER" />
    </http>

    <beans:bean id="digestFilter" class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
        <beans:property name="userDetailsService" ref="daoPersonal" />
        <beans:property name="authenticationEntryPoint" ref="digestEntryPoint" />
    </beans:bean>

    <beans:bean id="digestEntryPoint" class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
        <beans:property name="realmName" value="Contacts Realm via Digest Authentication" />
        <beans:property name="key" value="acegi" />
    </beans:bean>

    <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <authentication-manager>
        <authentication-provider user-service-ref="daoPersonal">
             <password-encoder ref="bcryptEncoder" />
        </authentication-provider>
    </authentication-manager>
 </beans:beans>

和我的PersonalDAO

and my PersonalDAO

 public class PersonalDAO extends NamedParameterJdbcDaoSupport implements UserDetailsService  {

 /*my other code
  ...
 */

 @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println(new Date() + " PersonalDAO loadUserByUsername: " + username);
         List<UserDetails> users = getJdbcTemplate().query(USER_QUERY, new String[] {username}, new RowMapper<UserDetails>() {
                public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                    String username = rs.getString(1);
                    String password = rs.getString(2);
                    boolean enabled = true;
                    Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
                    auths.add(new SimpleGrantedAuthority("ROLE_USER"));
                    return new User(username, password, enabled, true, true, true, auths);
                }
            });
         if(users.size()==0){
             throw new UsernameNotFoundException("");
         }
         System.out.println(new Date() + "Users Found: " + users.size());
         return users.get(0);
    }
 }

使用来自数据库的纯文本密码,在身份验证提供程序内部没有密码编码器的情况下,它可以按预期工作.但是使用密码编码器(并且数据库中的密码已更改为bcrypt编码的密码),浏览器会指出登录错误,并再次提示.从我的输出中,我可以看到我的PersonalDAO已被调用并找到了用户.

Without the password-encoder inside the authentication-provider it works as intended, using plaintext passwords from database. But with password-encoder (and password in the db changed to a bcrypt encoded one) the browser states the login was wrong and prompts again. From my output I can see that my PersonalDAO was called and found the user.

我的数据库中仍然有另一个用户,该用户仍然具有明文密码,我尝试使用该用户登录,同时仍使bcryptencoder处于活动状态,我在服务器日志中得到了该密码:

I still have another user in my db which still has a plaintext password, I tried to login with that one, while still having the bcryptencoder active I get this in my server log:

 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder matches
 WARNING: Encoded password does not look like BCrypt

现在我至少可以看到BCryptEncoder被调用了,但是它有一个匹配项,这意味着没有进行任何编码,而我仍然无法进入.(这可能是预期的).

Now I can at least see that the BCryptEncoder is called, but it got a match, meaning nothing got encoded, and I still can't get in. (which might be expected).

我想念什么?

日志输出不多,但这里有:

log output there isn't much but here goes:

Fri Dec 05 15:07:06 CET 2014 PersonalDAO loadUserByUsername: test
Fri Dec 05 15:07:06 CET 2014 Users Found: 1

db中的加密密码: $ 2a $ 10 $ HWX95PBi7pob2bmIHXka3ecMcfsSvEifV3Z6J0CAb3vpWs8N9j5xS

encrypted password in db: $2a$10$HWX95PBi7pob2bmIHXka3ecMcfsSvEifV3Z6J0CAb3vpWs8N9j5xS

推荐答案

HTTP摘要认证和BCrypt密码编码器无法结合使用.这是因为HTTP摘要算法要求密码以明文形式存储.您必须更改身份验证方法或删除密码编码.

The combination of HTTP Digest authentication and BCrypt password encoder is not possible. This is because the HTTP Digest algorithm requires that the password is stored in cleartext. You must either change authentication method or remove password encoding.

这篇关于使用带有默认身份验证提供程序的Spring-Security PasswordEncoder?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆