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;
}

3.整合

1、流程描述

1)、模拟增删改查
2)、未登录授权都不可以访问
3)、登录后根据用户权限,访问指定页面
4)、对于未授权页面,访问返回403:资源不可用

2、核心依赖

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

3、核心配置

package com.Boot.config;

import com.Boot.Security.UserDetailServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /**
* @Classname SpringSecurityConfig
* @Description TODO
* @Date 2019/11/6 19:59
* @Created by 远
*/
@Configuration
@EnableWebSecurity //启动springSecurity启动链
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { /**
* @return
* @Author 远
* @Description 代替认证管理器
* @Param
**/
/**
* 自定义认证数据源
*/
@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();
} /**
* @Author 远
* @Description 硬编码一个用户用于测试
* @Param
* @return
**/
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("ljw").password("123").authorities("ROLE_ADD");
}*/ /**
* @return
* @Author 远
* @Description 代替之前配置<security:http></security:http>
**/
@Override
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests()
//antMatchers指定页面,hasAnyAuthority指定拥有什么样的权限的用户可以访问
.antMatchers("/add").hasAnyAuthority("ROLE_ADD")
.antMatchers("/update").hasAnyAuthority("ROLE_UPDATE")
.antMatchers("/list").hasAnyAuthority("ROLE_SELECT")
.antMatchers("/delete").hasAnyAuthority("ROLE_DELETE")
//放行index和login页面
.antMatchers("/login").permitAll()
.antMatchers("/index").permitAll()
//拦截全部
.antMatchers("/**")
.fullyAuthenticated()
.and()
//解决页面csrf报错
.csrf().disable();
// 配置登录功能
http.formLogin().usernameParameter("user")
.passwordParameter("pwd")
.loginPage("/userLogin");
// 注销成功跳转首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe().rememberMeParameter("remeber");
}
}

4、认证

package com.Boot.Security;

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;
import org.springframework.stereotype.Service; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List; /**
* @Classname UserDetailServiceImpl
* @Description 认证
* @Date 2019/11/6 22:22
* @Created by 远
*/
@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){
//将所有的角色遍历到GrantedAuthority
grantedAuthorityList.add(new SimpleGrantedAuthority(role)) ;
}
}
//返回用户,用户的用户名,密码,以及权限
return new User(username,password,grantedAuthorityList);
}
}

5、接口

package com.Boot.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; /**
* @Classname productController
* @Description 增删改查
* @Date 2019/11/1 14:41
* @Created by 远
*/ @Controller
public class productController {
/**
* @Author 远
* @Description
* @Param
* @return
**/
@RequestMapping("/add")
public String add() {
return "product/add";
}
/**
* @Author 远
* @Description 商品修改
**/
@RequestMapping("update")
public String Update() {
return "product/update";
} /**
* @Author 远
* @Description 商品显示
**/
@RequestMapping("list")
public String list() {
return "product/list";
} /**
* @Author 远
* @Description 商品删除
**/
@RequestMapping("delete")
public String del() {
return "product/delete";
}
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("index")
public String index(){
return"index";
}
@RequestMapping("403")
public String forbidden(){
return "403";
} }

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>

Security整合spring boot的更多相关文章

  1. Spring Kafka整合Spring Boot创建生产者客户端案例

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 创建一个kafka-producer-master的maven工程.整个项目结构如下: ...

  2. PART 5: INTEGRATING SPRING SECURITY WITH SPRING BOOT WEB

    转自:http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/ ...

  3. Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器,包括Spring Security和Spring Boot

    2月14日,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器. 其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队将不再提供 ...

  4. 漫谈Spring Security 在Spring Boot 2.x endpoints中的应用(一)

    Spring Boot 2.x极大简化了默认的安全配置,并不是说有很多安全相关的配置,现在你只需要提供一个WebSecurityConfigurerAdapter继承类这样一个简单的操作,Spring ...

  5. spring boot:用spring security加强spring boot admin的安全(spring boot admin 2.3.0 / spring boot 2.3.3)

    一,spring boot admin的安全环节: 1,修改context-path,默认时首页就是admin, 我们修改这个地址可以更安全 2,配置ip地址白名单,有ip限制才安全, 我们使用了sp ...

  6. idea整合 spring boot jsp mybatis

    spring  boot  开发起来确实要简单许多 ,spring boot  包含了 spring mvc ;内置tomcat   ;启动只需要主方法即可 1.使用idea新建一个spring bo ...

  7. Spring Security +Oauth2 +Spring boot 动态定义权限

    Oauth2介绍:Oauth2是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的. 简单的来说,当用户登陆网站的时候,需要账号 ...

  8. 面试官:小伙子,你给我简单说一下RocketMQ 整合 Spring Boot吧

    前言 在使用SpringBoot的starter集成包时,要特别注意版本.因为SpringBoot集成RocketMQ的starter依赖是由Spring社区提供的,目前正在快速迭代的过程当中,不同版 ...

  9. 整合spring boot时操作数据库时报错Caused by: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.B

    原文:https://blog.csdn.net/u__f_o/article/details/82756701 一般出现这种情况,应该是没有扫描到对应的mapper包,即在启动类下配置MapperS ...

随机推荐

  1. .NET开发者必须学习.NET Core

    很多的.NET开发者在接触.Net Core之前,对于linux系统一点也不了解,也未曾有过主动去学习的念头.在接触了.Net Core之后才会慢慢学习linux相关知识,很多同学想转Java,这个很 ...

  2. Shell之Function与Source

    目录 Shell之Function与Source 参考 Fuction的编写 Source的使用 Shell之Function与Source

  3. 自适应布局display:-webkit-box的用法

    在web布局中,我们经常使用的是display:inline-block,display:flex,这些,但其实在进行移动端设备自适应布局中,-webkit-box布局更加合适 不同的浏览器有不同的前 ...

  4. Python 对cookies的处理——urllib2

    import urllib2 import cookielib cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2 ...

  5. Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用

    前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...

  6. Nginx开启Gzip压缩提升页面加载速度

    1.在 nginx 的conf 目录下新建 gzip.conf 文件 #开启gzip压缩 gzip on; #设置允许压缩的页面最小字节数 gzip_min_length 1k; #申请4个单位为16 ...

  7. [开源]如何使用goapp写你的后台管理系统_golang

    简析 基于 Gin + GORM + Casbin + vue-element-admin 实现的权限管理系统. 基于Casbin 实现RBAC权限管理. 前端实现: vue-element-admi ...

  8. 配置中心-Apollo

    配置中心-Apollo 2019/10/01 Chenxin 配置服务主要有 携程Apollo.百度Disconf.阿里ACM,目前以Apollo用户量最大.适用场景,多用于微服务,与K8S结合好. ...

  9. Python调用 Openstack 主要服务(keystone,nova,glance,neutron,heat)

    由于Openstack更新很快,现在准备搭建基于Queen版本的Openstack,Queen版本要求keystone版本为V3,所以之前大多数接口都不能用了,百度了一下都没有比较新的实例,官方文档又 ...

  10. 深入理解C#多线程 -戈多编程

    引用(http://www.cnblogs.com/luxiaoxun/p/3280146.html) 一.使用线程的好处   1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使 ...