- 导入SpringSecurity坐标
- 在web.xml中配置过滤器
- 编写spring-securiy配置文件
- 编写自定义认证提供者
- 用户新增时加密密码
- 配置页面的login和logout
- 获取登录用户的信息
一.SpringSecurity简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
如果要对Web资源进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。Spring security对Web资源的保护,就是靠Filter实现的。
二.SpringSecurity的使用
1.导入SpringSecurity的坐标
<!-- 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>
2.在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"> <!-- 1.解决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> <!-- 2.配置SpringMVC的前端控制器 --> <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> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- 3.配置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> </web-app>
3.编写SpringSecurity的配置文件(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: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"> <!-- 1.配置页面的放行规则(不需要登录验证的资源) --> <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> <!-- 2.页面的拦截规则 --> <http use-expressions="false"> <!-- 2.1当前用户必须有ROLE_USER的角色 才可以访问根目录及所属子目录的资源 --> <intercept-url pattern="/**" access="ROLE_USER"/> <!-- 2.2表单登陆,默认用户名和密码的name属性为:username和password,也可在这里配置 --> <form-login login-page="/shoplogin.html" default-target-url="/admin/index.html" authentication-failure-url="/shoplogin.html" always-use-default-target="true"/> <!-- 2.3关闭跨域攻击 --> <csrf disabled="true"/> <!-- 2.4为了解决frame框架访问问题默认是deny不允许访问,改成同一域下可以进行访问--> <headers> <frame-options policy="SAMEORIGIN"/> </headers> <!-- 2.5配置登出功能(页面注销连接到“/logout"即可完成退出到指定页面) --> <logout logout-success-url="/login.html"></logout> </http> <!-- 3.认证管理器 --> <authentication-manager> <!-- 3.1认证提供者:这里是写成固定的,也可以自定义 --> <authentication-provider> <user-service> <!-- 配置当前系统的用户 authorities该用户属于哪个角色:这里写成固定的 --> <user name="admin" password="123456" authorities="ROLE_USER"/> </user-service> </authentication-provider> <!-- 3.1认证提供者:这里是写成固定的,也可以自定义 --> <!-- ======================================================== --> <!-- 3.2通过自定义认证提供者,实现动态认证 --> <authentication-provider user-service-ref="userDetailService"> <!-- 认证时,先对用户输入的密码加密再和数据库的对比 --> <password-encoder ref="bcryptEncoder"></password-encoder> </authentication-provider> <!-- 3.2通过自定义认证提供者,实现动态认证 --> </authentication-manager> <!-- 4.认证类:配置的方式进行注入 --> <beans:bean id="userDetailService" class="cn.dintalk.service.UserDetailsServiceImpl"> <beans:property name="sellerService" ref="sellerService"></beans:property> </beans:bean> <!-- 5.引用dubbo 服务 --> <dubbo:application name="dintalk-shop-web" /> <dubbo:registry address="zookeeper://192.168.88.130:2181"/> <!-- 5.1配置的方式注入sellerService --> <dubbo:reference id="sellerService" interface= "cn.dintalk.sellergoods.service.SellerService"></dubbo:reference> <!-- 6.配置密码加密方式 --> <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></beans:bean> </beans:beans>
4.编写自定义认证提供者(如需自定义)
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; /** * 用户的登录认证 * @author Mr.song * @date 2019/06/06 12:26 */ public class UserDetailsServiceImpl implements UserDetailsService { /** * 提供set方法以注入sellerService */ private SellerService sellerService; public void setSellerService(SellerService sellerService) { this.sellerService = sellerService; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //1.根据用户名查询数据库 TbSeller seller = sellerService.findOne(username); //2.判断用户是否存在 if (seller != null){ //3.定义集合,封装用户的角色(这里角色少,写死.也可以从数据库查询) List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER")); if (seller.getStatus().equals("1")){//用户处于可以登录的状态 return new User(username,seller.getPassword(),grantedAuthorities); } } //3.用户不存在,认证失败 return null; } }
5.用户新增时加密密码(如需加密)
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * 增加 * @param seller * @return */ @RequestMapping("/add") public Result add(@RequestBody TbSeller seller){ try { //添加时进行密码的加密,登录时配置同样的加密器即可 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String newPws = passwordEncoder.encode(seller.getPassword()); seller.setPassword(newPws); sellerService.add(seller); return new Result(true, "增加成功"); } catch (Exception e) { e.printStackTrace(); return new Result(false, "增加失败"); } }
6.配置页面的login和logout
<!-- 1.login的配置要点:默认,登录框的name属性分别为username和password(也可在配置中修改) 登录表单提交方式为post,登录链接为:/login--> <form method="post" id="loginform" action="/login"> <input name="username" type="text" placeholder="邮箱/用户名/手机号"> <input name="password" type="password" placeholder="请输入密码"> <a onclick="document:loginform.submit()" target="_blank">登 录</a> </form> <!-- 2.logout的配置要点:默认,退出链接为:/logout即可 --> <a href="/logout" >注销</a>
7.获取登录用户的信息
import org.springframework.security.core.context.SecurityContextHolder; ... /** * 获取用户登录名进行展示 * @return */ @RequestMapping("/showName") public Map showName(){ //1.从认证处取得登录信息(除了username还可获取其他信息) String name = SecurityContextHolder.getContext().getAuthentication().getName(); //2.构建Map并返回 HashMap<String, String> map = new HashMap<>(); map.put("name",name); return map; }
关注微信公众号,随时随地学习
原文地址:https://www.cnblogs.com/dintalk/p/10987835.html
时间: 2024-10-26 04:26:51