以下是大体思路
1、导入坐标
<properties> <spring.version>4.2.4.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-huaweibc</artifactId> <version>${spring.version}</version> </dependency> <!--springSecurity需要引入的坐标--> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.1.0.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency>
2、web.xml
配置spring提供的代理过滤器。web.xml中配置spring框架的代理过滤器DelegatingFilterProxy
<!-- springSecurity相关配置--> <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>
3、spring-security配置文件
<?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:dubbo="http://code.alibabatech.com/schema/dubbo" 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.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> <http pattern="/css/**" security="none"></http> <http pattern="/img/**" security="none"></http> <http pattern="/js/**" security="none"></http> <http pattern="/plugins/**" security="none"></http>
<!--注册放行--> <http pattern="/seller/add.do" security="none"></http> <!-- 页面的拦截规则 use-expressions:是否启动SPEL表达式 默认是true --> <http use-expressions="false"> <!-- 当前用户必须有ROLE_USER的角色 才可以访问根目录及所属子目录的资源 --> <intercept-url pattern="/**" access="ROLE_USER"/> <!-- 开启表单登陆功能 --> <form-login login-page="/shoplogin.html" default-target-url="/admin/index.html" authentication-failure-url="/shoplogin.html" always-use-default-target="true"/> <csrf disabled="true"/> <!-- 为了解决前端iframe框架的不允许同窗口不同框跨域访问问题。访问问题默认是deny不允许访问,改成同一域下可以进行访问:默认为deny,如果是iframe页面管理页面会报x-frame-options,此处修改为sameorigin即可--> <headers> <frame-options policy="SAMEORIGIN"/> </headers>
<!--springSecurity的退出操作,我们什么都不写也可以,默认的controller访问路径为/logout--> <logout/> </http> <!-- 认证管理器 --> <authentication-manager> <authentication-provider user-service-ref="userDetailService">
<!--使用密码加密类,如果密码不需要加密注释下面即可--> <password-encoder ref="bcryptEncoder"></password-encoder> </authentication-provider> </authentication-manager> <!-- 认证类:该类是自定义类,实现了UserDetailsService接口,在该类中进行用户名和密码的判断 --> <beans:bean id="userDetailService" class="com.huawei.service.UserDetailsServiceImpl">
<!--此处需要为UserDetailService的实现类中注入一个依赖sellerService,避免产生父子容器问题,如果过是单体项目不用不用考虑该问题,通过再实现类中@Autowired直接注入即可--> <beans:property name="sellerService" ref="sellerService"></beans:property> </beans:bean> <!-- 引用dubbo ,服务引用dubbo 服务,如果不使用分布式下面的可以注释掉 --> <dubbo:application name="huawei-shop-web" /> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <dubbo:reference id="sellerService" interface="com.huawei.sellergoods.service.SellerService"></dubbo:reference> <!--密码加密类,该类是使用的spring提供的加密类--> <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></beans:bean> </beans:beans>
4、UserDetailService的实现类(把这个类加载进spring容器中采用xml配置,不要使用注解,避免父子容器问题)
public class UserDetailsServiceImpl implements UserDetailsService { private SellerService sellerService; public void setSellerService(SellerService sellerService) { this.sellerService = sellerService; } @Override public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { //完成认证授权功能 //根据name查询数据库或者seller对象,seller对象需要sellergoods_service进行查询 TbSeller seller = sellerService.findOne(name); //name就是sellerId //不仅根据sellerid找到该商家,而且还需要审核后 if(seller!=null && "1".equals(seller.getStatus())){ //拼接角色列表 List<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("ROLE_USER")); //用户名 密码 角色列表 return new User(name, seller.getPassword(), authorities); } return null; } }
5、测试
直接运行测试,上方源码是搭建在分布式项目Dubbo+zookeeper运行的
6、拓展:
6.1、获取SpringSecurity中的用户信息
String name =SecurityContextHolder.getContext().getAuthentication().getName();