Spring Security 框架使用
阅读原文时间:2023年07月08日阅读:1

更多内容,前往IT-BLOG


Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring 应用上下文中配置的 Bean,充分利用了Spring IoC,DI(控制反转 Inversion of Control ,DI:Dependency Injection 依赖注入)和 AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。


【1】创建 Maven工程(war形式):spring-security-demo
【2】修改 pom.xml目录,如下:

1
2 3 4.12 4 4.2.4.RELEASE 5 4.0.0 6 2.5 7 2.8.4 8 3.4.7 9 0.1 10 3.2.8 11 1.2.2 12 1.2.15 13 5.1.32 14 1.0.9 15 1.3.1 16 2.3.23 17 5.11.2 18 3.2.3.RELEASE 19 4.10.3 20 2012_u6 21
22 23 24 org.springframework 25 spring-core 26 ${spring.version} 27 28 29 org.springframework 30 spring-web 31 ${spring.version} 32 33 34 35 org.springframework 36 spring-webmvc 37 ${spring.version} 38 39 40 41 org.springframework 42 spring-context-support 43 ${spring.version} 44 45 46 47 org.springframework 48 spring-test 49 ${spring.version} 50 51 52 53 org.springframework 54 spring-jdbc 55 ${spring.version} 56 57 58 59 org.springframework.security 60 spring-security-web 61 4.1.0.RELEASE 62 63 64 65 org.springframework.security 66 spring-security-config 67 4.1.0.RELEASE 68 69 70 71 javax.servlet 72 servlet-api 73 2.5 74 provided 75 76 77
78 79 80 81 82 org.apache.maven.plugins 83 maven-compiler-plugin 84 3.2 85 86 1.7 87 1.7 88 UTF-8 89 90 91 92 org.apache.tomcat.maven 93 tomcat7-maven-plugin 94 95 96 9090 97 98 / 99 100 101 102

注意:如果只是给自己的项目中嵌入 Spring Security 安全框架,只需要添加如下两个 jar 包即可。

1 2 org.springframework.security 3 spring-security-web 4 4.1.0.RELEASE 5
6
7 8 org.springframework.security 9 spring-security-config 10 4.1.0.RELEASE 11

【3】创建 web.xml 文件(通过 Spring Security 拦截需要处理的请求和引入 Spring Security 的配置文件)。

1
2 http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app\_2\_5.xsd" 5 version="2.5"> 6 7 8 contextConfigLocation 9 classpath:spring-security.xml 10 11 12 13 org.springframework.web.context.ContextLoaderListener 14 15 16 17 18 19 springSecurityFilterChain 20 org.springframework.web.filter.DelegatingFilterProxy 21 22 23 springSecurityFilterChain 24 /* 25 26

【4】创建 Spring Security 配置文件:spring-security.xml(与 web.xml 中引入的配置文件对应),代码中有配置的详细说明注解。

1
2
3 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd 10 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> 11 12 14 15 16 17 18 19 20 21 22 25 26 30 31 34 38 42 43 44 45 46 47 48 49 50 51 57 58 59 60 61 62 63 64 65 66 72 73 77 78 79 80 84

【5】需要自己创建:login.html(登录页面 如下)、index.html(登录成功跳转页面)、login_error.html(登录失败跳转页面)

1
2 3 4 5 登陆 6 7 8 --欢迎登陆我的系统-- 9

10 用户名:
11 密码:
12 13
14 15


【1】配置文件中配置的,登录时用户名和密码的业务逻辑处理类(实现 UserDetailsService:框架自带的接口),注意:普通 demo 不需要此部分,主要用于真是环境登录逻辑的处理。

1 public class UserDetailServiceImpl implements UserDetailsService {
2 //当通过配置文件的形式,引入服务类时需要设置set方法。
3 private SellerService sellerService;
4
5 public void setSellerService(SellerService sellerService) {
6 this.sellerService = sellerService;
7 }
8
9 @Override
10 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
11 //GrantedAuthority : 定义用户角色,需要实现的接口
12 List list =new ArrayList<>();
13 //用户添加角色,SimpleGrantedAuthority可以定义用户角色,实现了GrantedAuthority接口,
14 //格式必须以(ROLE_)开头
15 list.add(new SimpleGrantedAuthority("ROLE_SELLER"));
16 //从数据库中获取用户信息。
17 TbSeller seller = sellerService.findOne(username);
18 if(seller != null) {
19 //返回username:传过来的参数。seller.getPassword:数据库中获取到的用户密码。
20 //list:用户的所有角色,可以从数据库中获取
21 return new User(username, seller.getPassword(), list);
22 }else {
23 return null;
24 }
25 }
26 }

【2】BCrypt 加密过程(配置中说明了 BCrypt 与 MD5 的区别)。

1 @RequestMapping("/add")
2 public Result add(@RequestBody TbSeller seller){
3 try {
4 //BCrypt加密使用的对象BCryptPasswordEncoder
5 BCryptPasswordEncoder cryptPasswordEncoder = new BCryptPasswordEncoder();
6 //使用encode方法对传入的密码加密,返回30位的字符串
7 String encode = cryptPasswordEncoder.encode(seller.getPassword());
8 //业务处理:接入对象中
9 seller.setPassword(encode);
10 //调用服务层,入库
11 sellerService.add(seller);
12 return new Result(true, "增加成功");
13 } catch (Exception e) {
14 e.printStackTrace();
15 return new Result(false, "增加失败");
16 }
17 }


SecurityContextHolder 用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保存在 SecurityContextHolder 中。SecurityContextHolder 默认使用 ThreadLocal  策略来存储认证信息。看到 ThreadLocal 也就意味着,这是一种与线程绑定的策略。Spring Security 在用户登录时自动绑定认证信息到当前线程,在用户退出时,自动清除当前线程的认证信息。但这一切的前提,是你在 web 场景下使用 Spring Security。
☏ 因为身份信息是与线程绑定的,所以可以在程序的任何地方使用静态方法获取用户信息。一个典型的获取当前登录用户的姓名的例子如下所示:getAuthentication() 返回了认证信息。

1 @RequestMapping("/name")
2 public Map getName(){
3 //获取登录名
4 String name = SecurityContextHolder.getContext().getAuthentication().getName();
5 Map map = new HashMap<>();
6 map.put("loginName", name);
7 return map;
8 }

☏ Authentication 源码:

1 package org.springframework.security.core;// <1>
2 public interface Authentication extends Principal, Serializable { // <1>
3 Collection getAuthorities(); // <2>
4 Object getCredentials();// <2>
5 Object getDetails();// <2>
6 Object getPrincipal();// <2>
7 boolean isAuthenticated();// <2>
8 void setAuthenticated(boolean var1) throws IllegalArgumentException;
9 }

【1】Authentication 是 Spring Security 包中的接口,直接继承自 Principal 类,而 Principal 是位于 java.security 包中的。可以见得,Authentication 在 Spring Security 中是最高级别的身份/认证的抽象。
【2】由这个顶级接口,我们可以得到用户拥有的权限信息列表,密码,用户细节信息,用户身份信息,认证信息。
authentication.getPrincipal() 返回了一个 Object,我们将 Principal 强转成了Spring Security 中最常用的 UserDetails,这在Spring Security 中非常常见,接口返回 Object,使用 instanceof 判断类型,强转成对应的具体实现类。接口详细解读如下:
getAuthorities():权限信息列表,默认是GrantedAuthority接口的一些实现类,通常是代表权限信息的一系列字符串。
getCredentials():密码信息,用户输入的密码字符串,在认证过后通常会被移除,用于保障安全。
getDetails():细节信息,web应用中的实现接口通常为 WebAuthenticationDetails,它记录了访问者的 ip地址和 sessionId的值。
getPrincipal():最重要的身份信息,大部分情况下返回的是UserDetails接口的实现类,也是框架中的常用接口之一。


----关注公众号,获取更多内容_----_