Spring Security 入门学习--数据库认证和授权
- 首先是使用的SpringBoot框架
基础需要的pom以来如下,基础的springboot项目的创建就不一一赘述了。
<!--spring web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--jpa 对数据库操作的框架 类似mybatis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--页面引擎 thymeleaf模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--mysql数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- 加入必须的security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
数据库连接配置文件
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://xx.xx.xx.xx:3306/springsecurity?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=user
spring.datasource.password=password #设置运行时打印sql语句
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update #关闭thymeleaf缓存
spring.thymeleaf.cache=false #不用数据库认证时默认的用户名和密码
#spring.security.user.name=admin
#spring.security.user.password=1234
- 实体类***********重要***********
对于实体类的创建:
- 用户表包含权限表
- 用户表不包含权限表
笔者使用的是用户表包含权限表的方式,那么不包含权限表该怎么解决呢?
创建一个新的实体类,如SecurityUser 继承User 实现UserDetails 它包含User的内容和UserDetails的内容,对于权限的设置就不一样了
重点注意这个方法 getAuthorities ,它来将权限交给security管理 暂时可以用Null值 在UserDetailsService中具体赋值
@Entity
public class User implements Serializable, UserDetails { private String username; private String password; private String role; public User(){} public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) { this.username = username; } public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
} /**
* 指示用户的账户是否已过期。无法验证过期的账户。
* 如果用户的账户有效(即未过期),则返回true,如果不在有效就返回false
*/
@Override
public boolean isAccountNonExpired() {
return true;
} /**
* 指示用户是锁定还是解锁。无法对锁定的用户进行身份验证。
* 如果用户未被锁定,则返回true,否则返回false
*/
@Override
public boolean isAccountNonLocked() {
return true;
} /**
* 指示用户的凭证(密码)是否已过期。过期的凭证阻止身份验证
* 如果用户的凭证有效(即未过期),则返回true
* 如果不在有效(即过期),则返回false
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
} /**
* 指示用户是启用还是禁用。无法对禁用的用户进行身份验证
* 如果启用了用户,则返回true,否则返回false
*/
@Override
public boolean isEnabled() {
return true;
} /**
* 得到用户的权限,如果权限表和用户表是分开的,我们需要在重新定义一个实体类实现UserDetails 并且继承于User类
* 交给security的权限,放在UserDetailService进行处理
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
//角色必须以ROLE_开头,如果数据库没有,则需要加上 至于角色为什么必须要以ROLE_开头 笔者没有进行深究
authorities.add(new SimpleGrantedAuthority("ROLE_"+this.role));
return authorities;
}
}
- 此处就先不谈security的config配置吧,后面会提到
我们还没有用到数据库中的数据,在此我们需要改造UserServiceImpl类,让其实现 UserDetailsService 并重写其中的 loadUserByUsername 方法,这是数据库认证的必要流程,贴代码:
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Autowired
UserDao userDao; /**
* 实现security认证实现的方法
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.error("username:" + username);
//option这个东西请读者自行研究,此处可以直接是一个user,optional只是用于判断空值,避开空指针异常的
Optional<User> byUsername = userDao.findByUsername(username);
if (!byUsername.isPresent()) {
throw new UsernameNotFoundException("用户名不存在,请先注册后登录!");
}else{
//权限表和用户表分开************按照下面方式,如果不是,直接返回带有权限信息的User对象
//查询的权限在此处可以通过数据库查询,并且赋值
//List<GrantedAuthority> authorities=new ArrayList<>();
//authorities.add(new SimpleGrantedAuthority("ROLE_SPITTER"))
//新创建一个SecurityUser(自定义实现了UserDetails的类)
//将authorites放到该对象中,并返回出去
return byUsername.get();
}
}
}
- 对于security的配置******************重要
新创建一个配置类继承 WebSecurityConfigurerAdapter
需要注意的几个方法(重写的方法):
configure(HttpSecurity http) : htpp请求安全处理
configure(AuthenticationManagerBuilder auth) : 自定义数据库权限认证
configure(WebSecurity web) : WEB安全
@Configuration
@EnableWebSecurity // 开启注解
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启注解 //自定义了一个springSecurity安全框架的配置类 继承WebSecurityConfigurerAdapter,重写其中的方法configure,
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserServiceImpl userService; @Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() //接触防止跨域请求
.authorizeRequests()
.antMatchers("/toLogin","/templates/**","/logout","/toIndex").permitAll() //忽略认证的url
.anyRequest().authenticated() //其他的url都需要被认证才可以访问
.and()
.formLogin() //允许自定义表单登录
.loginPage("/toLogin") //这是action地址 不能写具体页面 确定自定义登录页 自己不需要写login方法 登录是由security提供
.loginProcessingUrl("/login") //这是html中form中action的值 必须要对应
.defaultSuccessUrl("/toIndex") //默认登录成功会跳转的controller
//关于登录失败的提示信息,请读者自行解决
.failureForwardUrl("/login-error")
.failureUrl("/login-error");
} //密码加密,最新的security必须使用密码加密
@Bean
public PasswordEncoder passwordEncoder(){
//使用BCcypt加密
return new BCryptPasswordEncoder();
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从数据库读取的用户进行身份认证 实现了userDetailsService的类
auth.userDetailsService(userService)
.passwordEncoder(passwordEncoder());
} //解除对静态资源的保护
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**","/templates/**");
} }
- 接下来是Controller和页面
- 必须要登录成功才可以访问其他的接口,没有通过认证会一直卡在login
@Controller
public class UserController {
@Autowired
UserServiceImpl userService; @RequestMapping("/toIndex")
public String index(){
return "index";
} @RequestMapping("/toLogin")
public String login(){
return "login";
}
//定义需要访问的权限
@PreAuthorize("hasAnyRole('ROLE_admin')")
@RequestMapping("/sayHello")
@ResponseBody
public String sayHello(){
return "hello";
}
//定义需要访问的权限
@PreAuthorize("hasAnyAuthority('ROLE_user')")
@RequestMapping("/sayYes")
@ResponseBody
public String sayYes(){
return "yes";
} }
html页面
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--layui css-->
<link rel="stylesheet" th:href="@{js/layui-v2.5.5/layui/css/layui.css}">
<!--layui js-->
<script th:src="@{js/layui-v2.5.5/layui/layui.js}"></script>
<!--jquery-->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<title>登录页面</title>
</head>
<body>
<!--这里请注意action的值需要与loginProcessingUrl 相对应-->
<form action="/login" method="post">
<div class="layui-form-item">
<label class="layui-form-label">输入框</label>
<div class="layui-input-inline">
<input type="text" id="username" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码框</label>
<div class="layui-input-inline">
<input type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn layui-btn-warm" lay-submit lay-filter="formDemo">登录</button>
</div>
</div>
</form>
</body>
</html>
第一次写博客 感觉还是有点乱,请和谐讨论,笔者也是看了很多其他的博客慢慢弄出来的,希望大家不要害怕麻烦,慢慢来,引入就不贴了,看了太多 也不知道谁是谁的
Spring Security 入门学习--数据库认证和授权的更多相关文章
- Spring Security + JJWT 实现 JWT 认证和授权
关于 JJWT 的使用,可以参考之前的文章:JJWT 使用示例 一.鉴权过滤器 @Component public class JwtAuthenticationTokenFilter extends ...
- Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战
一. 前言 [APP 移动端]Spring Security OAuth2 手机短信验证码模式 [微信小程序]Spring Security OAuth2 微信授权模式 [管理系统]Spring Se ...
- spring security进阶 使用数据库中的账户和密码认证
目录 spring security 使用数据库中的账户和密码认证 一.原理分析 二.代码实现 1.新建一个javaWeb工程 2.用户认证的实现 3.测试 三.总结 spring security ...
- Spring Security 入门(基本使用)
Spring Security 入门(基本使用) 这几天看了下b站关于 spring security 的学习视频,不得不说 spring security 有点复杂,脑袋有点懵懵的,在此整理下学习内 ...
- SpringBoot集成Spring Security入门体验
一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...
- Spring Security 解析(三) —— 个性化认证 以及 RememberMe 实现
Spring Security 解析(三) -- 个性化认证 以及 RememberMe 实现 在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把 ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_05-SpringSecurityOauth2研究-搭建认证服务器
3 Spring Security Oauth2研究 3.1 目标 本项目认证服务基于Spring Security Oauth2进行构建,并在其基础上作了一些扩展,采用JWT令牌机制,并自定 义了用 ...
- Spring Security 入门详解(转)
1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别 处理 ...
- Spring Security 入门详解
序:本文主要参考 spring实战 对里面的知识做一个梳理 1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完 ...
随机推荐
- JS中Math.random()的使用和扩展
Math.random()方法返回大于等于 0 小于 1 的一个随机数.对于某些站点来说,这个方法非常实用,因为可以利用它来随机显示一些名人名言和新闻事件. 在连续整数中取得一个随机数 值 = Mat ...
- PHP usort() 函数
------------恢复内容开始------------ 实例 使用用户自定义的比较函数对数组 $a 中的元素进行排序:Sort the elements of the $a array usin ...
- PHP rad2deg() 函数
实例 把弧度转换为角度: <?phpecho rad2deg(pi()) . "<br>";echo rad2deg(pi()/4);?>高佣联盟 www. ...
- 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...
- luogu P3264 [JLOI2015]管道连接
LINK:管道连接 一张无向图 有P个关键点 其中有K个集合 各个集合要在图中形成联通块 边有边权 求最小代价. 其实还是生成树问题 某个点要和某个点要在生成树中 类似这个意思. 可以发现 是斯坦纳树 ...
- IDEA查看项目日志Version Control、log
打开IDEA找到以下两处: 右下角git 黄色指针指向当前项目的版本 选中初始化项目,点击右键选择"Checkout Revision 1db2f3d5",如下图 ...
- SparkSQL & Spark on Hive & Hive on Spark
刚开始接触Spark被Hive在Spark中的作用搞得云里雾里,这里简要介绍下,备忘. 参考:https://blog.csdn.net/zuochang_liu/article/details/82 ...
- C++关于智能指针
有四种: auto_ptr<class T> unique_ptr<class T> shared_ptr<class T> weak_ptr<class T ...
- 为写程序而生的连字字体 Fira Code
Fira Code,等宽的编程连字字体 **等宽 ** 是指所有字符的宽度相同,如: W 和 i 用一样的宽度去显示 连字(ligatures)为文字排印的一个特性,比如「f」和「 i」放在一起的时候 ...
- Android VideoView未解决,动态读取权限、BottomNavigationView的用法
昨天想写的,但是因为Video的毛病,是真找不出为啥了.百度也没用,学长也不清楚. 百度了那么久,大概得出结论,电脑的视频是不能用它来播放的... ..经过两天的奋斗,我居然搞定了,我的视频终于出来了 ...