版权声明:转载请标明出处 https://blog.csdn.net/keyuzhang/article/details/89236089
用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。 特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。 BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。
1.web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 解决post乱码 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- spring security 权限控制 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-security.xml</param-value> </context-param> <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> </web-app>
2.spring-security.xml配置
<?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" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <http pattern="/*.html" security="none"/> <http pattern="/css/**" security="none"/> <http pattern="/img/**" security="none"/> <http pattern="/js/**" security="none"/> <http pattern="/plugins/**" security="none"/> <http pattern="/seller/add.do" security="none"/> <!-- use-expressions:设置是否启动SpEL表达式,默认值是true。 --> <http use-expressions="false"> <!-- 配置SpringSecurity的拦截路径(拦截规则) * pattern:配置拦截规则。 /* 代表的是根路径下的所有资源(不包含子路径) /**代表的是根路径下所有的资源(包含子路径) * access:设置角色 角色命名 ROLE_角色名称 如: ROLE_USER --> <intercept-url pattern="/**" access="ROLE_SELLER"/> <!-- 开启表单验证 username-parameter="username" password-parameter="password" login-page :登录页面名称 以 / 开始 default-target-url :登录成功后跳转的页面 login-processing-url:提交的路径的设置 默认值"/login" 可以修改 --> <form-login login-page="/shoplogin.html" default-target-url="/admin/index.html" always-use-default-target="true" authentication-failure-url="/shoplogin.html"/> <!-- 不使用csrf的校验 --> <csrf disabled="true"/> <!-- 配置框架页面不拦截 --> <headers> <frame-options policy="SAMEORIGIN"/> </headers> <!-- 注销的配置 --> <logout logout-url="/logout" logout-success-url="/shoplogin.html" /> </http> <!-- 配置认证管理器 页面传递过来的 用户名 密码 123 先加密 我们通过用户名去Mysql查询出来的密码 $2a$10$cnp.NvUj4pU.byyHtGo5a.m2mwLgemb18e/a4wH09Ib9jeYcyXifm --> <authentication-manager> <!-- 认证的提供者 --> <authentication-provider user-service-ref="userDetailService"> <password-encoder ref="passwordEncoder"/> </authentication-provider> </authentication-manager> <!-- 配置自定义的认证类 --> <beans:bean id="userDetailService" class="cn.itcast.core.service.UserDetailServiceImpl"> <beans:property name="sellerService" ref="sellerService"></beans:property> </beans:bean> <!-- 引用dubbo 服务 --> <dubbo:application name="pinyougou-shop-web" /> <dubbo:registry address="zookeeper://192.168.200.128:2181"/> <dubbo:reference id="sellerService" interface="cn.itcast.core.service.SellerService" /> <!-- 加密实现类 --> <beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> </beans:beans>
3.Controller层创建UserDetailServiceImpl(此类非服务提供方的service层,因为spring公司要调一个用户的实现类)
package cn.itcast.core.service; /** * 自定义实现类 从Mysql查询数据 * @author lx * */ public class UserDetailServiceImpl implements UserDetailsService{ private SellerService sellerService; public void setSellerService(SellerService sellerService) { this.sellerService = sellerService; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub //通过用户名查询用户对象 Seller seller = sellerService.findOne(username); if(null != seller){ //有用户 //判断 状态 1:审核通过的 if("1".equals(seller.getStatus())){ // 通过了 return new User(用户名,密码,权限) Set<GrantedAuthority> authorities = new HashSet<>(); authorities.add(new SimpleGrantedAuthority("ROLE_SELLER")); return new User(username,seller.getPassword(),authorities); } } return null; } }