springsecurity使用:登录与校验
首先是引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
默认方案:
首次使用这个空项目的时候他会给你一个默认的账号
账号名为user
密码在控制台输出如下图

这时再进入后端会直接弹到一个/login的地址,输入上述账号密码即可查看路由的具体内容,也可以输出/logout退出登录
springsercurity本质是一个过滤器链

在默认案例中UsernamePasswordAuthenticationFilter中会调用UserDetailService接口的InMemoryUserDetailManager获取用户信息 ,后续我们需要修改成在数据库中查询信息而非内存中

自拟方案:
登录
- 自定义登录接口:调用ProviderManager认证,通过则生成jwt,并把用户数据存入redis,自定义UserDetailService,把从内存查数据改成从数据库查
- 自定义service继承UserDetailService
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//查询用户信息
User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserName, username));
if(Objects.isNull(user)){
throw new RuntimeException("用户名或密码错误");
}
String password = user.getPassword();
//todo 查询权限信息
//封装返回
LoginUser loginUser=new LoginUser();
loginUser.setUser(user);
return loginUser;
} - 实现LoginUser类,继承的UserDetails
public class LoginUser implements UserDetails
- 这里如果进行测试的话,会报错:PasswordEncoder会拿获得的密码和数据库比对,但是要求数据库内的格式为{id}password,根据id去判断加密方式。所以我们写的时候会用BC替换掉这个方法
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
} }注:这里使用了bc加密之后数据库的密码也应在添加时替换成加密后的密码.bc提供了matches()和encode()两种方法
- 添加拦截配置,给登录方法放行一下
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeRequests()
.antMatchers("/user/login").anonymous() //匿名访问:未授权前可以使用,授权之后就不再可以使用
.anyRequest().authenticated(); // 必须要授权才可以使用
} - 登录service
public ResponseResult login(User user) {
//进行用户认证
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
if (Objects.isNull(authenticate)) {
throw new RuntimeException("用户名或密码错误");
}
LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
String id = loginUser.getUser().getId().toString();
String jwt = JwtUtil.createJWT(id);
HashMap<String, String> map = new HashMap<>();
map.put("token", jwt);
redisCache.setCacheObject("login:"+id,loginUser);
return new ResponseResult("登录成功", 200, map);
}
- 自定义service继承UserDetailService
- 校验:获取token后解析获取userid,通过redis获取其中用户数据,并将其存入SecurityContextHolder中
- 配置过滤器
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//获取token并解析
String token = request.getHeader("token");
if (!StringUtils.hasText(token)) {
filterChain.doFilter(request, response);
return;
}
String userId;
try {
Claims claims = JwtUtil.parseJWT(token);
userId = claims.getSubject();
} catch (Exception e) {
throw new RuntimeException(e);
}
//从redis中获取用户信息再存入securityContextHolder
String redisKey = "login:" + userId;
LoginUser loginUser = redisCache.getCacheObject(redisKey);
if(Objects.isNull(loginUser)){
throw new RuntimeException("用户未登录");
}
//todo 权限信息还没写
SecurityContextHolder.getContext().
setAuthentication(new UsernamePasswordAuthenticationToken(loginUser,null,null));
filterChain.doFilter(request, response);
}
} - 添加过滤器
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
- 配置过滤器
为什么要存入信息到SecurityContextHolder中:后续步骤都需要从其中取数据,如果是未认证的状态会导致后面不放行
为什么上述两个位置同样用到了UsernamePasswordAuthenticationToken方法但作用不同:Authentication表示当前访问系统的用户,封装了用户相关信息。
在第一个构造函数中,1.5登录service:我们使用了AuthenticationManager.authenticate()这一方法对数据进行逻辑验证,验证失败则返回结果为null
而第二个构造函数中,2.1配置过滤器:这里手动设置安全信息,此时已经通过安全检查了

//config的一些参数使用案例
.authorizeRequests()
.antMatchers("/user/login").anonymous()//匿名访问,是指在未授权前可以使用,授权后就不能再使用此功能了
.antMatchers("/example").permitAll()//什么状态都可以访问
.anyRequest().authenticated();//授权后才可以访问
springsecurity使用:登录与校验的更多相关文章
- Python3.x:获取登录界面校验码图片
Python3.x:获取登录界面校验码图片 实例代码: # python3 # author lizm # datetime 2018-06-01 18:00:00 # -*- coding: utf ...
- crm 系统项目(一) 登录,注册,校验
crm 系统项目(一) 登录,注册,校验 首先创建一个Django项目,关于配置信息不多说,前面有~ models.py文件下创建需要的表格信息,之后导入数据库 from django.db impo ...
- MVC下用户登录状态校验的问题以及解决方案--------------Action全局过滤器的使用
前言当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的 ...
- Spring-Security自定义登录页&inMemoryAuthentication验证
Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架.框架下内容比较多,可以做到按照角色权限对请求路径进行限制.今天主要验证自定义登录页,在内存用户存储中进行请求 ...
- SpringSecurity 进行自定义Token校验
背景 Spring Security默认使用「用户名/密码」的方式进行登陆校验,并通过cookie的方式存留登陆信息.在一些定制化场景,比如希望单独使用token串进行部分页面的访问权限控制时,默认方 ...
- SpringSecurity+Token实现权限校验
1.Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配 ...
- access登录窗口校验代码一
Private Sub login_Click()If IsNull(Me.username) ThenMsgBox "请输入用户名!", vbExclamationElseIf ...
- SpringBoot+SpringSecurity之如何forword到登录页面
当我们在项目中引入了SpringSecurity框架进行身份校验的时候,如果某个请求需要用户身份认证,那么SpringSecurity会将用户redirect到登录页面.但是有些时候我们希望是forw ...
- SpringSecurity中的Authentication信息与登录流程
目录 Authentication 登录流程 一.与认证相关的UsernamePasswordAuthenticationFilter 获取用户名和密码 构造UsernamePasswordAuthe ...
- js经典校验之注册与登录校验
平时都专注于后台功能的实现和逻辑需求的分析及数据库方面的设计,很少关注前端的设计,而项目开发过程中专门负责后台是不太可能的事,所以前端我们也需要会用,除了漂亮的首页等其他的交给美工来做,一些功能性的东 ...
随机推荐
- .net C# System.Text.Json 如何将 string类型的“true”转换为布尔值 解决方案
直接上解决方法的代码 先定义一个转换顺,代码如下: public sealed class AnhBoolConverter : JsonConverter<bool?> { public ...
- 恭喜PaddleOCRSharp开源项目通过PaddleOCR社区常规赛优秀项目首次评选
PaddleOCR优秀社区项目推荐: PaddleOCR社区常规赛首次评选结果已于日前出炉,本次优秀项目推广为大家带来的是[部署篇]:️ PaddleOCR的.NET调用库:包含文本识别.文本检测.基 ...
- Excel相关技巧
(1)如何实现EXCEL某个单元格满足条件整行变色? 链接:https://jingyan.baidu.com/article/75ab0bcba47c19d6864db2cf.html (2)获取表 ...
- UML建模工具Astah Pro 8破解教程2022最新最详细版
(2022最新最详细版)UML建模工具Astah Pro 8破解教程 本文作者严正声明:拒绝盗版行为,打击盗版,痛恨吃白食的家伙,我一直都是坚定思想,有钱了一定要支持正版,所以此文档贡献,只为学习交流 ...
- bpmnjs
在 bpmn.js 中,`bpmnModeler.get()` 方法用于获取不同的模块,你可以通过这些模块来访问和操作 BPMN 模型的不同部分.以下是一些常用的模块和对应的用途: 1. **Canv ...
- 操作标签的属性和属性值 table表格
// 操作标签的属性和属性值 // 特殊的属性 // 可以直接通过 点语法或者[]语法来操作的属性 // id 和 class ...
- asp.net core mvc 使用quartz
参照了:https://www.cnblogs.com/dangzhensheng/p/10496278.html 1.新建任务类ReportJob.cs,这个类里就是具体任务了. using Qua ...
- 利用ADB获取APP资源
最近小编经常受到失眠的困扰,因为在编写一个安卓体能评定的软件,同时又在构思一个桌面管理应用,不管是构想还是操作上都遇到了很多难题,所以寄希望于小编手机上的一款软件,因为版权问题,就不说出它叫啥名字了. ...
- manim边学边做--MathTex
上一篇介绍的SingleStringMathTex主要用来显示只有一行的数学公式,对于复杂的数学公式,可以使用MathTex类. MathTex类继承自SingleStringMathTex,在其基础 ...
- NXP i.MX 8M Mini开发板规格书(四核ARM Cortex-A53 + 单核ARM Cortex-M4,主频1.6GHz)
1 评估板简介 创龙科技TLIMX8-EVM是一款基于NXP i.MX 8M Mini的四核ARM Cortex-A53 + 单核ARM Cortex-M4异构多核处理器设计的高性能评估板,由核心板和 ...