SpringBoot——Spring Security 框架
优质博文:IT-BLOG-CN
一、Spring Security 简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的 Bean,充分利用了Spring IoC,DI(控制反转 Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
二、Spring Security 入门Demo
【1】创建Maven工程(war形式):spring-security-demo
【2】修改pom.xml目录,如下:
4.12
4.2.4.RELEASE
4.0.0
2.5
2.8.4
3.4.7
0.1
3.2.8
1.2.2
1.2.15
5.1.32
1.0.9
1.3.1
2.3.23
5.11.2
3.2.3.RELEASE
4.10.3
2012_u6
org.springframework
spring-core
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework.security
spring-security-web
4.1.0.RELEASE
org.springframework.security
spring-security-config
4.1.0.RELEASE
javax.servlet
servlet-api
2.5
provided
org.apache.maven.plugins
maven-compiler-plugin
3.2
1.7
1.7
UTF-8
org.apache.tomcat.maven
tomcat7-maven-plugin
9090
/
注意:如果只是给自己的项目中嵌入Spring Security安全框架,只需要添加如下两个jar包即可。
org.springframework.security spring-security-web 4.1.0.RELEASE org.springframework.security spring-security-config 4.1.0.RELEASE
【3】创建web.xml文件(通过Spring Security拦截需要处理的请求和引入Spring Security的配置文件)。
contextConfigLocation classpath:spring-security.xml org.springframework.web.context.ContextLoaderListener springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /*
【4】创建Spring Security配置文件:spring-security.xml(与 web.xml中引入的配置文件对应),代码中有配置的详细说明注解。
<!-- use-expressions -为是否使用 Spring 表达式语言( SpEL ),默认为true ,如果开启,则拦截的配置应该写成以下形式 --> <!-- 对密码进行bcrypt加密,比较时需要解密后处理,bcrypt与MD5不同, MD5加密后相同的密码生成相同的16位字符创,bcrybt相同的密码加密后生成不同的30位字符串, 相当于MD5+盐 --> <!-- 当自己的项目需要使用另一个项目中的服务类时 ,需要通过dubbo引入项目 dubbo标签 --> <!-- -->
【5】需要自己创建:login.html(登录页面 如下)、index.html(登录成功跳转页面)、login_error.html(登录失败跳转页面)
登陆 --欢迎登陆我的系统-- 用户名:
密码:
三、项目实战中,后台业务逻辑实现重要代码摘取,供实战中使用
【1】配置文件中配置的,登录时用户名和密码的业务逻辑处理类(实现UserDetailsService:框架自带的接口),注意:普通demo不需要此部分,主要用于真是环境登录逻辑的处理。
public class UserDetailServiceImpl implements UserDetailsService {
//当通过配置文件的形式,引入服务类时需要设置set方法。
private SellerService sellerService;
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//GrantedAuthority : 定义用户角色,需要实现的接口
List list =new ArrayList();
//用户添加角色,SimpleGrantedAuthority可以定义用户角色,实现了GrantedAuthority接口,
//格式必须以(ROLE_)开头
list.add(new SimpleGrantedAuthority("ROLE_SELLER"));
//从数据库中获取用户信息。
TbSeller seller = sellerService.findOne(username);
if(seller != null) {
//返回username:传过来的参数。seller.getPassword:数据库中获取到的用户密码。
//list:用户的所有角色,可以从数据库中获取
return new User(username, seller.getPassword(), list);
}else {
return null;
}
}
}
【2】BCrypt加密过程(配置中说明了BCrypt与MD5的区别)。
@RequestMapping("/add")
public Result add(@RequestBody TbSeller seller){
try {
//BCrypt加密使用的对象BCryptPasswordEncoder
BCryptPasswordEncoder cryptPasswordEncoder = new BCryptPasswordEncoder();
//使用encode方法对传入的密码加密,返回30位的字符串
String encode = cryptPasswordEncoder.encode(seller.getPassword());
//业务处理:接入对象中
seller.setPassword(encode);
//调用服务层,入库
sellerService.add(seller);
return new Result(true, "增加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "增加失败");
}
}
四、当程序中需要用户名时,可通过 SecurityContextHolder 对象获取
☏ SecurityContextHolder用于存储安全上下文security context的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保存在SecurityContextHolder中。SecurityContextHolder默认使用ThreadLocal策略来存储认证信息。看到ThreadLocal也就意味着,这是一种与线程绑定的策略。Spring Security在用户登录时自动绑定认证信息到当前线程,在用户退出时,自动清除当前线程的认证信息。但这一切的前提,是你在web场景下使用Spring Security。
☏ 因为身份信息是与线程绑定的,所以可以在程序的任何地方使用静态方法获取用户信息。一个典型的获取当前登录用户的姓名的例子如下所示:getAuthentication() 返回了认证信息。
@RequestMapping("/name")
public Map getName(){
//获取登录名
String name = SecurityContextHolder.getContext().getAuthentication().getName();
Map map = new HashMap();
map.put("loginName", name);
return map;
}
☏ Authentication源码:
package org.springframework.security.core;//
public interface Authentication extends Principal, Serializable { //
Collection getAuthorities(); //
Object getCredentials();//
Object getDetails();//
Object getPrincipal();//
boolean isAuthenticated();//
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
【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接口的实现类,也是框架中的常用接口之一。
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/d69b176eaa.html
