springsecurity教程一
1.springsecurity学习目标

2.1 springsecurity简介


2.2 springsecurity快速入门demo
1):使用idea快速创建springboot项目,并勾选如下2个依赖即可,springboot会为我们做很多自动配置

2):定义一个loginController,并定义一个页面跳转方法:

重定向到main.html页面,我们需要准备如下几个页面:login.html main.html,放到stacit目录下:
mian.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
登录成功!!!
</body>
</html>
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆页面</title>
</head>
<form action="/login" method="post">
用户登陆
用户名:<input type="text" name="username">
密码: <input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
当我们启动项目运行,并访问我们的login.html页面时,发现并不是我们写的那个页面:

默认的登录名是user,密码会在程序启动的时候生成一个打印到控制台:

2.3 UserDetailService详解
在真实的系统中,我们希望用户的信息来自数据库,而不是写死的或者账户密码都是springsecurity自动生成给我们的,我们就需要实现UserDetailsService接口,实现相应的方法,然后配置authentication-provider,指定我们自定义的UserDetailService。
这就要看下springsecurtiy给我们提供的UserDetailsService这个接口
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
这里的返回结果UserDetails也是一个接口,实现了序列化:
public interface UserDetails extends Serializable {
// 获取所有权限,不能返回null
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
而UserDetails这个接口,springsecurity提供了默认的实现类,下图中的User,不要和我们自己定义的混淆
这里springsecurity的逻辑是,先根据登录时提供的用户名username,去数据库查询出该用户的密码,权限,是否过期等数据,并返回。拿到这个密码后和前端填写的密码进行比较,如果相同则表示认证通过。

user的两个构造方法:
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
Assert.isTrue(username != null && !"".equals(username) && password != null, "Cannot pass null or empty values to constructor");
this.username = username;
this.password = password;
this.enabled = enabled;
this.accountNonExpired = accountNonExpired;
this.credentialsNonExpired = credentialsNonExpired;
this.accountNonLocked = accountNonLocked;
this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities));
}
2.4 PasswordEncoder详解
上面讲到如果我们想实现我们自定义的验证逻辑,需要实现UserDetailsService接口,同时还需要实现 PasswordEncoder接口,对密码进行加密和匹配验证

2.5自定义登录逻辑
代码结构图:

@Configuration
public class SecurityConfig {
// 使用自定义逻辑时那,springsecurity要求我们项目容器中有BCryptPasswordEncoder的实例,所以不能直接new使用,没有在容器中
@Bean
public BCryptPasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
@Service
public class UserServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder pw;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("执行了loadUserByUsername方法");
// 1.查询数据库看用户名是否存在,不存在抛出异常UsernameNotFoundException
// 为了方便这里不再去查询数据库,模拟下
if (!"admin".equals(username)) {
throw new UsernameNotFoundException("用户名不存在");
}
// 2.根据用户名查询数据库中的密码(这个密码肯定是加密后的,不会是明文存储)进行解析,或者直接把密码放入构造方法
String password = pw.encode("123");//这样模拟password是数据库查询出来的加密密码
// 查询出来后封装user对象返回,后面如果经过和前端输入的user比对校验通过,则user这个用户将会有“admin,normal”的权限,这个实际也是要从数据库中查询后配置的,这里模拟下
User user = new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));
return user;
}
}
这样写好之后,重启我们的项目,发现输入用户admin,密码123即可访问我们的服务,这样一个简单的自定义登录逻辑就实现好了,后面还需要继续研究这个流程的详细原理,先会用哈。
springsecurity教程一的更多相关文章
- CRL快速开发框架系列教程一(Code First数据表不需再关心)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- NGUI系列教程一
NGUI是Unity的一个插件,使用它来制作你的游戏UI必定将事半功倍.为什么这么说呢?首先我们说说GUI与NGUI的区别,GUI是Unity自带的绘制界面工具,它的成像原理是基于表层的,所以执行效率 ...
- Quartz教程一:使用quartz
原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...
- redis学习教程一《Redis的安装和配置》
redis学习教程一<Redis的安装和配置> Redis的优点 以下是Redis的一些优点. 异常快 - Redis非常快,每秒可执行大约110000次的设置(SET)操作,每秒大约可执 ...
- Cobalt Strike使用教程一
Cobalt Strike使用教程一 0x00 简介 Cobalt Strike是一款基于java的渗透测试神器,常被业界人称为CS神器.自3.0以后已经不在使用Metasploit框架而作为 ...
- Activiti5.10简易教程一
Activiti5.10简易教程一 一搭建环境 1.1 JDK 6+ activiti 运行在版本 6 以上的 JDK 上.转到 Oracle Java SE 下载页面,点击按钮“下载 JDK ” ...
- 无废话SharePoint入门教程一[SharePoint概述]
一.前言 听说SharePoint也有一段时间了,可一直处在门外.最近被调到SharePoint实施项目小组,就随着工作一起学习了一下实施与开发.但苦于网上SharePoint入门的东西实在太少,导致 ...
- JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获
先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...
- MVC5 + EF6 入门完整教程一:从0开始
第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定" 会让人困惑,而且东西太多容易忘记 ...
随机推荐
- 腾讯IOT安卓开发初探
目录 腾讯IOT 安卓开发初探 Tecent IOT 开发平台的使用 新建项目 创建产品 添加自定义功能 设备开发 微信小程序配置 面板配置 新建设备 使用设备 安卓开发 前置配置 data.json ...
- 解决github下载速度慢问题
众所周知,GitHub是一个巨大的开源宝库,以及程序员和编程爱好者的聚集地,包括我之前推荐的诸多优秀的开源项目全部都是位于GitHub上.但是每当我们看到优秀的开源项目,准备去 下(bai)载(pia ...
- NOIP初赛篇——06数制转换
进位计数制的基本概念 将数字符号按顺序排列成数位,并遵照某种由低到高的进位方式计数表示数值的方法,称作为计数制. 十进制 十进制计数制由0.1.2.3.4.5.6.7.8.9共10个数字符号组成. ...
- VsCode配置Go语言插件
前言 宇宙第一IDE对于笔记本来说还是太过沉重了 VsCode虽然差了点但是胜在插件多且够轻量 VsCode的安装/汉化参考我之前的博客 https://www.cnblogs.com/chnmig/ ...
- LeetCode662 二叉树最大宽度
给定一个二叉树,编写一个函数来获取这个树的最大宽度.树的宽度是所有层中的最大宽度.这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空. 每一层的宽度被定义为两个端点(该层 ...
- spring ioc踏出第一步
spring IOC(容器) AOP(面向切面编程) IOC容器:他的功能就是可以整合像 Structs2 .Hibernate.Mybatis: IOC:控制反转:所谓的控制就是控制资源的获取方法, ...
- 谈谈你不知道的gist
1.Gist是什么关于Gist的详细介绍,请阅读官方文档About gists,下面只简略介绍部分功能: Gist是一种与其他人共享代码片段和粘贴的简单方法. 当您需要与同事或朋友共享示例代码或技术时 ...
- 基于Dockfile构建JAVA环境网站镜像
查看本地目录 [root@docker tomcat]# ls apache-tomcat-8.5.16.tar.gz Dockerfile jdk-8u91-linux-x64.tar.gz ...
- Linux下nginx的安装以及环境配置
参考链接 https://blog.csdn.net/qq_42815754/article/details/82980326 环境: centos7 .nginx-1.9.14 1.下载 并解压 ...
- 18V转5V,18V转3.3V,18V转3V稳压芯片,0.01A-3A输出
18V转5V,18V转3.3V,18V转3V, 18V转5V稳压芯片,18V转3.3V稳压芯片,18V转3V稳压芯片, 18V常降压转成5V电压,3.3V电压和3V电压给其他芯片或设备供电,适用于这个 ...