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

2020-01-09  本文已影响0人  Ronal丶

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

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

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

上一篇下一篇

猜你喜欢

热点阅读