搭建/升级Spring-Security-5.x,搭建过程&踩坑
2020-01-09 本文已影响0人
Ronal丶
作为一个程序员,想有自己的一个开源框架,通过借鉴前辈经验和查阅官方文档是必不可少的步骤,因此本文对基本的概念不做过多解释,如有需要请移步官方文档。
Spring Security是一个提供身份验证、授权和防范常见攻击的框架。由于同时支持命令式和反应式应用程序,它是保护基于spring的应用程序的实际标准。
下面是整合搭建过程
- 在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>
- 在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>
- 编写
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
文章未完成,后续继续完善