【问题标题】:How to add MD5 or SHA hash to spring security?如何将 MD5 或 SHA 哈希添加到 Spring Security?
【发布时间】:2013-09-02 22:17:29
【问题描述】:

我正在开发一个使用 Java EE、Spring 安全框架和 Oracle 11g 数据库的应用程序。我需要在 Spring 安全性中添加一个 MD5 哈希,但我没有成功。

到目前为止我做了什么:

1-在最初的几周里,我尝试将 md5 哈希添加到我的应用程序中,而不向 springsecuritycontext.xml 添加任何代码,我成功了。

这就是我所做的:

在名为ma.dyaralmansour.zkgui.policy的包中有两个类。第一个是PolicyManager,这个类实现了spring-security UserDetailService。第二个称为 LoginLoggingPolicyService,这个类作为一个方面从 Spring AOP 调用,用于记录。

这就是我所做的:

       *** I added an MD5Password class to the ma.dyaralmansour.zkgui.policy and I added some code to the PolicyManager class to activate the hash and it's working.

我现在的问题是:

我的所有密码都使用 MD5 哈希值进行哈希处理,但是当我使用普通密码时,我无法再访问该应用程序。

现在我有 2 个选项,但我不知道如何实现它们:

1-在MD5password类中有一个名为testPassword(String clearTextTestPassword,String encodedActualPassword)的方法

它将普通密码与存储在数据库中的散列密码进行比较,但我不明白如何将其添加到我的 policymanager 类中。

2 - 完全删除我所做的一切,只关注 Spring 安全性的配置,以便在我使用普通密码时对密码进行哈希处理并访问应用程序。

或者有其他解决方案吗?

http://www.mediafire.com/download/gxgda63wyhkpehn/DamPromoZK4.rar

<!-- Spring namespace-based configuration -->

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:zksp="http://www.zkoss.org/2008/zkspring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd
                    http://www.springframework.org/schema/aop   
                    http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">



<!-- Enable the @Secured annotation to secure service layer methods -->
<global-method-security secured-annotations="enabled" />

<http auto-config="true">

    <!-- ###  If we have our own LoginPage. So we must    ### -->
    <!-- ###     tell Spring the name and the place.      ### -->
    <!-- ###     In our case we take the same page        ### -->
    <!-- ###     for a error message by a failure.        ### -->
    <!-- ### Further the page after a successfully login. ### -->
    <form-login login-page="/index.zul" 

        authentication-failure-url="/index.zul?login_error=1"
        default-target-url="/AccueilIntranet.zul" />

    <!-- ###   Tell Spring where it goes after logout.    ### -->
    <!-- ###          logout-url is a action url.         ### -->
    <logout logout-url="/j_spring_logout" logout-success-url="/index.zul" />

    <!-- ### Define the pages that are to be intercepted  ### -->
    <!-- ### It is parsed from top to bottom. Means that  ### -->
    <!-- ### the most specific pattern is standing on TOP ### -->
    <!-- ###         and the CATCH ALL is on BOTTOM!      ### -->
    <intercept-url pattern="/pages/**" access="IS_AUTHENTICATED_REMEMBERED" filters="none" />
    <intercept-url pattern="/WEB-INF/pages/**" access="IS_AUTHENTICATED_REMEMBERED" filters="none"/>

    <!-- ### The root page is accessible by everyone but  ### -->
    <!-- ###    internally spring makes a login and       ### -->
    <!-- ###     this user becames a UserDetails          ### -->
    <!-- ###   (in there are the ip-address and others)   ### -->
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" filters="none"/>

    <!-- ###           Per user one session !!            ### -->
    <concurrent-session-control max-sessions="1" />
</http>

<!-- ###   We define the kind of authentification with a  ### -->
<!-- ###          so called authentication-provider       ### -->
<!-- ###   So we have our users stored in a DB we use     ### -->
<!-- ###   our own user-service class and point to her.   ### -->
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>




<!-- ###   The Implementation of the Interface            ### -->
<!-- ###      UserDetailService for the logged in         ### -->
<!-- ###              user and his rights                 ### -->
<beans:bean id="myUserDetailsService" class="ma.dyaralmansour.zkgui.policy.PolicyManager">
    <beans:property name="userService" ref="userService" />
</beans:bean>



<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder hash="md5"/>
</authentication-provider>




    <!-- ###   This aspect call automatically the methode     ### -->
    <!-- ###   'loginLogging' which is for writing a log for  ### -->
    <!-- ###   all successfully and failed logins, if a       ### -->
    <!-- ###   methode is called that handles the             ### -->
    <!-- ###    Authentication.                               ### -->
    <beans:bean id="LoginLoggingPolicyService"
        class="ma.dyaralmansour.zkgui.policy.LoginLoggingPolicyService">
        <beans:property name="loginLoggingService" ref="loginLoggingService" />
    </beans:bean>






    <aop:config>
        <aop:aspect id="LoginLoggingAspect" ref="LoginLoggingPolicyService">
            <aop:pointcut id="authPointcut"
                expression="execution(public org.springframework.security.Authentication org.springframework.security.providers.AuthenticationProvider.authenticate(org.springframework.security.Authentication))" />
            <aop:around pointcut-ref="authPointcut" method="loginLogging" />
        </aop:aspect>
    </aop:config>

</beans:beans>

【问题讨论】:

    标签: spring-mvc encryption hash spring-security md5


    【解决方案1】:

    为什么要重新发明轮子? Spring Security 支持开箱即用的密码哈希,这只是一个配置问题。 UserDetailService 的自定义实现必须简单地返回为用户名找到的用户(而不是检查密码或其他什么)。然后 Spring Security 将使用配置的哈希检查密码。

    通过将密码编码器添加到您的 &lt;authentication-provider .. &gt; 元素来适当地配置 Spring Security

    <authentication-provider user-service-ref="myUserDetailsService">
        <password-encoder hash="md5"/>
    </authentication-provider>
    

    您可能还想查看Spring Security documentation

    另一个改进建议是不要使用 AOP 进行日志记录(假设这是您唯一要做的)实现 ApplicationListener 并监听 AbstractAuthenticationEvents。您可能需要检查默认的 LoggerListener 以获得简单的工作示例。

    【讨论】:

    • 我将此代码添加到我的 springsecuritycontext.xml 并删除了 MD5password 类和我在 policymanager 类中完成的代码,但是当我运行应用程序并使用普通密码时,它不会变成散列我不知道那几行代码实际上是做什么的,你能向我解释一下吗?
    • 我如何告诉 spring 从我的数据库中读取数据并使用哈希密码来连接到应用程序?
    • 这是通过添加上面提到的配置来完成的。 “使用普通密码不会被散列”是什么意思?哪个密码,什么时候应该散列?请使用您现在拥有的当前设置(配置和代码)更新您的问题。
    • 我添加了你上面提到的配置,我删除了我之前所做的任何事情,我只保留了你给我的代码,所以当我尝试使用例如 login=admin 登录应用程序时,我查看我的数据库,登录没有被散列
    • 不,您没有...您没有像我的代码示例中那样添加&lt;password-encoder /&gt; 元素。所以基本上你什么都没有。另外,在您不应该检查服务中的密码之前,spring 会为您执行此操作。 框架一起工作,而不是反对或围绕框架。
    【解决方案2】:

    使用新的 BCryptPasswordEncoder:

    http://static.springsource.org/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html

    它会自动为你的密码加盐。

    我推荐 BCrypt,因为它功能强大,速度慢,并且没有已知的弱点。 “慢”实际上是哈希算法中你想要的一个特性,因为这意味着如果有人窃取了你的密码,它需要更长的时间来破解。

    SHA 256 被削弱。 MD5 肯定坏了。

    【讨论】:

    • 你能否向我解释一下这是我第一次使用 spring 并且我仍然没有一个明确的想法,你能告诉我我是否应该在我发布的代码中实现 BCryptpassword我的问题?
    • 你必须非常小心“慢”。如果您正在使用 session-less 代码,那么让一切都变得非常缓慢会很痛苦。到目前为止,我想到的最好的解决方法是为存储的密码保留强散列,但是在前面放置一个更便宜的透明内存缓存,这样使用之前使用的正确密码可以更快地进入。这个想法是让合法用户在不受持续攻击的系统上不必支付太多费用。
    猜你喜欢
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2010-11-25
    • 2016-03-16
    • 2013-09-08
    • 2021-09-03
    相关资源
    最近更新 更多