本文源码:GitHub·点这里 || GitEE·点这里

一、Security简介

1、基础概念

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

2、核心API解读

1)、SecurityContextHolder

最基本的对象,保存着当前会话用户认证,权限,鉴权等核心数据。SecurityContextHolder默认使用ThreadLocal策略来存储认证信息,与线程绑定的策略。用户退出时,自动清除当前线程的认证信息。

初始化源码:明显使用ThreadLocal线程。

private static void initialize() {
if (!StringUtils.hasText(strategyName)) {
strategyName = "MODE_THREADLOCAL";
}
if (strategyName.equals("MODE_THREADLOCAL")) {
strategy = new ThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals("MODE_INHERITABLETHREADLOCAL")) {
strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals("MODE_GLOBAL")) {
strategy = new GlobalSecurityContextHolderStrategy();
} else {
try {
Class<?> clazz = Class.forName(strategyName);
Constructor<?> customStrategy = clazz.getConstructor();
strategy = (SecurityContextHolderStrategy)customStrategy.newInstance();
} catch (Exception var2) {
ReflectionUtils.handleReflectionException(var2);
}
}
++initializeCount;
}

2)、Authentication

源代码

public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

源码分析

1)、getAuthorities,权限列表,通常是代表权限的字符串集合;
2)、getCredentials,密码,认证之后会移出,来保证安全性;
3)、getDetails,请求的细节参数;
4)、getPrincipal, 核心身份信息,一般返回UserDetails的实现类。

3)、UserDetails

封装了用户的详细的信息。

public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}

4)、UserDetailsService

实现该接口,自定义用户认证流程,通常读取数据库,对比用户的登录信息,完成认证,授权。

public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

5)、AuthenticationManager

认证流程顶级接口。可以通过实现AuthenticationManager接口来自定义自己的认证方式,Spring提供了一个默认的实现,ProviderManager。

public interface AuthenticationManager {
Authentication authenticate(Authentication var1) throws AuthenticationException;
}

二、与SpringBoot2整合

1、流程描述

1)、三个页面分类,page1、page2、page3
2)、未登录授权都不可以访问
3)、登录后根据用户权限,访问指定页面
4)、对于未授权页面,访问返回403:资源不可用

2、核心依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

3、核心配置

/**
* EnableWebSecurity注解使得SpringMVC集成了Spring Security的web安全支持
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 权限配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 配置拦截规则
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/page1/**").hasRole("LEVEL1")
.antMatchers("/page2/**").hasRole("LEVEL2")
.antMatchers("/page3/**").hasRole("LEVEL3");
// 配置登录功能
http.formLogin().usernameParameter("user")
.passwordParameter("pwd")
.loginPage("/userLogin");
// 注销成功跳转首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe().rememberMeParameter("remeber");
}
/**
* 自定义认证数据源
*/
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception{
builder.userDetailsService(userDetailService())
.passwordEncoder(passwordEncoder());
}
@Bean
public UserDetailServiceImpl userDetailService (){
return new UserDetailServiceImpl () ;
}
/**
* 密码加密
*/
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/*
* 硬编码几个用户
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("spring").password("123456").roles("LEVEL1","LEVEL2")
.and()
.withUser("summer").password("123456").roles("LEVEL2","LEVEL3")
.and()
.withUser("autumn").password("123456").roles("LEVEL1","LEVEL3");
}
*/
}

4、认证流程

@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Resource
private UserRoleMapper userRoleMapper ;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 这里可以捕获异常,使用异常映射,抛出指定的提示信息
// 用户校验的操作
// 假设密码是数据库查询的 123
String password = "$2a$10$XcigeMfToGQ2bqRToFtUi.sG1V.HhrJV6RBjji1yncXReSNNIPl1K";
// 假设角色是数据库查询的
List<String> roleList = userRoleMapper.selectByUserName(username) ;
List<GrantedAuthority> grantedAuthorityList = new ArrayList<>() ;
/*
* Spring Boot 2.0 版本踩坑
* 必须要 ROLE_ 前缀, 因为 hasRole("LEVEL1")判断时会自动加上ROLE_前缀变成 ROLE_LEVEL1 ,
* 如果不加前缀一般就会出现403错误
* 在给用户赋权限时,数据库存储必须是完整的权限标识ROLE_LEVEL1
*/
if (roleList != null && roleList.size()>0){
for (String role : roleList){
grantedAuthorityList.add(new SimpleGrantedAuthority(role)) ;
}
}
return new User(username,password,grantedAuthorityList);
}
}

5、测试接口

@Controller
public class PageController {
/**
* 首页
*/
@RequestMapping("/")
public String index (){
return "home" ;
}
/**
* 登录页
*/
@RequestMapping("/userLogin")
public String loginPage (){
return "pages/login" ;
}
/**
* page1 下页面
*/
@PreAuthorize("hasAuthority('LEVEL1')")
@RequestMapping("/page1/{pageName}")
public String onePage (@PathVariable("pageName") String pageName){
return "pages/page1/"+pageName ;
}
/**
* page2 下页面
*/
@PreAuthorize("hasAuthority('LEVEL2')")
@RequestMapping("/page2/{pageName}")
public String twoPage (@PathVariable("pageName") String pageName){
return "pages/page2/"+pageName ;
}
/**
* page3 下页面
*/
@PreAuthorize("hasAuthority('LEVEL3')")
@RequestMapping("/page3/{pageName}")
public String threePage (@PathVariable("pageName") String pageName){
return "pages/page3/"+pageName ;
}
}

6、登录界面

这里要和Security的配置文件相对应。

<div align="center">
<form th:action="@{/userLogin}" method="post">
用户名:<input name="user"/><br>
密&nbsp;&nbsp;&nbsp;码:<input name="pwd"><br/>
<input type="checkbox" name="remeber"> 记住我<br/>
<input type="submit" value="Login">
</form>
</div>

三、源代码地址

GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理的更多相关文章

  1. SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ...

  2. SpringBoot2.0 整合 Shiro 框架,实现用户权限管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.Shiro简介 1.基础概念 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.作为一款安全 ...

  3. springboot2.0整合springsecurity前后端分离进行自定义权限控制

    在阅读本文之前可以先看看springsecurity的基本执行流程,下面我展示一些核心配置文件,后面给出完整的整合代码到git上面,有兴趣的小伙伴可以下载进行研究 使用maven工程构建项目,首先需要 ...

  4. SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题

    本文源码:GitHub·点这里 || GitEE·点这里 一.传统Session认证 1.认证过程 1.用户向服务器发送用户名和密码. 2.服务器验证后在当前对话(session)保存相关数据. 3. ...

  5. SpringBoot2.0整合SpringSecurity实现自定义表单登录

    我们知道企业级权限框架一般有Shiro,Shiro虽然强大,但是却不属于Spring成员之一,接下来我们说说SpringSecurity这款强大的安全框架.费话不多说,直接上干货. pom文件引入以下 ...

  6. SpringBoot2.0 整合 ElasticSearch框架,实现高性能搜索引擎

    本文源码:GitHub·点这里 || GitEE·点这里 一.安装和简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful ...

  7. SpringBoot2.0整合SpringSecurity实现WEB JWT认证

    相信很多做技术的朋友都做过前后端分离项目,项目分离后认证就靠JWT,费话不多说,直接上干活(写的不好还请多多见谅,大牛请绕行) 直接上代码,项目为Maven项目,结构如图: 包分类如下: com.ap ...

  8. (十三)整合 SpringSecurity 框架,实现用户权限管理

    整合 SpringSecurity 框架,实现用户权限管理 1.Security简介 1.1 基础概念 1.2 核心API解读 2.SpringBoot整合SpringSecurity 2.1 流程描 ...

  9. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理

    一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...

随机推荐

  1. scrapy框架(二)

    scrapy框架(二) 一.scrapy 选择器 概述: Scrapy提供基于lxml库的解析机制,它们被称为选择器. 因为,它们“选择”由XPath或CSS表达式指定的HTML文档的某部分. Sca ...

  2. [NOIP模拟]文本编辑器 题解

    bsoj5089 文本编辑器 /* 题意描述 九发明了一个完美的文本编辑器.这个编辑器拥有两个光标(cursor),所以九能够同时在两处地方插入和删除文本.这个编辑器除了正常的编辑功能以外,还有一些只 ...

  3. k8s~跨namespace的service相互访问

    在k8s里,你可以通过服务名去访问相同namespace里的服务,然后服务可以解析到对应的pod,从而再由pod转到对应的容器里,我们可以认为这个过程有两个port的概念,service port 就 ...

  4. IM即时通信软件设计

    参考资料: 架构篇:https://yq.aliyun.com/articles/698301 模型篇:https://yq.aliyun.com/articles/701593 实现篇:https: ...

  5. 利用PyInstaller打包exe文件

    前言 平常我们通过Python写完一些小脚本之后,如果使用不频繁的话,一般会选择在DOS界面直接跑脚本,或者在IDE中运行.但当我们需要频繁使用某些脚本,或者在没有Python环境的机器上也能顺利运行 ...

  6. pycharm安装第三方包问题解决

    pycharm安装第三方包问题解决 pycharm是一个基于python的非常好用的集成开发环境,而python有许多非常不错的开源第三方库,这就需要将一些这样的第三方库导入到我们的项目中去了.然而, ...

  7. 关于js的一些被忽视但也很重要的知识点

    以为懂了,实际没懂.对新知识保持好奇心很有必要,但对原有知识也要更深入了解其细节.温故知新,"新",应该是自己不懂的,亦或是遗忘了的,亦或是...... 问题1: Object.p ...

  8. WPF炫酷UI及动画

    偶然看见了一张图,感觉挺好看的,花了点时间将他转化成了我代码仓库的一部分.虽然不难但也费时间.其中除了背景是百度的一张底图,其他所有内容均通过WPF的Path.Line.TextBlock.Borde ...

  9. JavaWeb学习——Servlet相关的接口和类

    JavaWeb学习——Servlet相关的接口和类 摘要:本文主要学习了Servlet相关的接口和类. Servlet的接口和类 三种方式 实现Servlet有三种方式: 实现javax.servle ...

  10. Git实战指南----跟着haibiscuit学Git(第六篇)

    笔名:  haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...