美文网首页
搭建/升级Spring-Security-5.x,搭建过程&踩坑

搭建/升级Spring-Security-5.x,搭建过程&踩坑

作者: Ronal丶 | 来源:发表于2020-01-09 15:55 被阅读0次

    作为一个程序员,想有自己的一个开源框架,通过借鉴前辈经验和查阅官方文档是必不可少的步骤,因此本文对基本的概念不做过多解释,如有需要请移步官方文档

    Spring Security是一个提供身份验证、授权和防范常见攻击的框架。由于同时支持命令式和反应式应用程序,它是保护基于spring的应用程序的实际标准。

    下面是整合搭建过程

    1. 在web.xml中添加filter
    <!-- Spring ..........-->
    <!-- 字符编码encoding ..........-->
     <!-- Spring Session ..........-->
     <!-- Spring Secutiry的过滤器链配置 -->
     <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>
    
    1. 在Spring配置文件选中引入Spring Security
    
        <!--启用@AsjectJ支持-->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        <!-- 配置文件config.properties -->
        <context:property-placeholder location="classpath:config.properties" ignore-unresolvable="true"
                                      local-override="true" ignore-resource-not-found="true"/>
    
        <import resource="classpath*:spring/spring-mybatis.xml"/>
        <import resource="classpath*:spring/spring-redis.xml"/>
        <import resource="classpath*:spring/spring-security.xml"/>
    
    </beans>
    
    1. 编写spring-security.xml
     <?xml version="1.0" encoding="UTF-8" ?>
    <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
           xmlns="http://www.springframework.org/schema/security"
           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.1.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security.xsd">
    
        <!--不进行拦截的静态资源-->
        <http pattern="/resources/**" security="none"/>
        <http pattern="/lib/**" security="none"/>
    
        <!--权限配置及自定义登录界面-->
        <http access-decision-manager-ref="accessDecisionManager">
            <csrf disabled="true"/>
            <intercept-url pattern="/login" access="permitAll()"/>
            <intercept-url pattern="/WEB-INF/views/login.html" access="permitAll"/>
            <intercept-url pattern="/verifiCode" access="permitAll"/>
            <intercept-url pattern="/common/**" access="permitAll"/>
            <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
            <access-denied-handler error-page="/WEB-INF/views/403.html"/>
    
            <form-login
                    login-page="/login"/>
                    <!--authentication-success-handler-ref="loginSuccessHandler"-->
                    <!--authentication-failure-handler-ref="loginFailureHandler"/>-->
            <!--登出-->
            <logout logout-url="/logout"/>
            <headers defaults-disabled="true">
                <cache-control/>
            </headers>
        </http>
        <!--登录成功和登录失败处理器-->
        <beans:bean id="loginSuccessHandler" class="com.ssm.security.LoginSuccessHandler">
            <beans:property name="defaultTargetUrl" value="/"/>
        </beans:bean>
        <beans:bean id="loginFailureHandler" class="com.ssm.security.LoginFailureHandler"/>
        <!--决策管理器-->
        <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
            <beans:constructor-arg name="decisionVoters">
                <beans:list>
                    <beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
                    <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
                    <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
                </beans:list>
            </beans:constructor-arg>
        </beans:bean>
    
        <!--认证管理器-->
        <authentication-manager alias="myAuthenticationManager">
            <authentication-provider user-service-ref="userDetailsService">
                <password-encoder ref="PasswordEncoder"/>
    
            </authentication-provider>
        </authentication-manager>
        <beans:bean id="userDetailsService" class="com.ssm.security.CustomUserDetailsService"/>
    
        <!-- 密码管理 PasswordEncoder-->
        <beans:bean id="PasswordEncoder" class="org.springframework.security.crypto.password.DelegatingPasswordEncoder">
            <beans:constructor-arg index="0" value="bcrypt"/>
            <beans:constructor-arg index="1">
                <beans:map>
                    <beans:entry key="bcrypt" value-ref="bcryptEncoder"/>
                    <beans:entry key="sha256" value-ref="passwordManagerStandard"/>
                </beans:map>
            </beans:constructor-arg>
        </beans:bean>
        <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
        <beans:bean id="passwordManagerStandard" class="com.ssm.security.passwordManager">
            <beans:property name="siteWideSecret" value="Zxa1xxxxxxuvBMlY"/>
            <beans:property name="defaultPassword" value="123456"/>
        </beans:bean>
    
    </beans:beans>
    

    这里的密码管理器用DelegatingPasswordEncoder,我这里填充了两个密码解析实现,一个是springsecurity推荐的BCryptPasswordEncoder,一个是模拟老密码用的passwordManagerStandard

    对于密码管理推荐阅读一篇介绍密码加密文章PasswordEncoder简介

    java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    

    这个错主要发生在Spring-Sercurity5.X版本上,例如SpringBoot2.x。导致这个错误发生主要原因就是在之前版本中的NoOpPasswordEncoder被DelegatingPasswordEncoder取代了,而你保存在数据库中的密码没有没有指定加密方式。
    解决方案:将数据库老密码按照加密方式增加前缀,例:{sha256}xxxxxxmmmmxxxxx

    文章未完成,后续继续完善

    相关文章

      网友评论

          本文标题:搭建/升级Spring-Security-5.x,搭建过程&踩坑

          本文链接:https://www.haomeiwen.com/subject/ieohactx.html