• 首先是使用的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
  • 实体类***********重要***********

  对于实体类的创建:

  1. 用户表包含权限表
  2. 用户表不包含权限表

  笔者使用的是用户表包含权限表的方式,那么不包含权限表该怎么解决呢?

    创建一个新的实体类,如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 入门学习--数据库认证和授权的更多相关文章

  1. Spring Security + JJWT 实现 JWT 认证和授权

    关于 JJWT 的使用,可以参考之前的文章:JJWT 使用示例 一.鉴权过滤器 @Component public class JwtAuthenticationTokenFilter extends ...

  2. Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战

    一. 前言 [APP 移动端]Spring Security OAuth2 手机短信验证码模式 [微信小程序]Spring Security OAuth2 微信授权模式 [管理系统]Spring Se ...

  3. spring security进阶 使用数据库中的账户和密码认证

    目录 spring security 使用数据库中的账户和密码认证 一.原理分析 二.代码实现 1.新建一个javaWeb工程 2.用户认证的实现 3.测试 三.总结 spring security ...

  4. Spring Security 入门(基本使用)

    Spring Security 入门(基本使用) 这几天看了下b站关于 spring security 的学习视频,不得不说 spring security 有点复杂,脑袋有点懵懵的,在此整理下学习内 ...

  5. SpringBoot集成Spring Security入门体验

    一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...

  6. Spring Security 解析(三) —— 个性化认证 以及 RememberMe 实现

    Spring Security 解析(三) -- 个性化认证 以及 RememberMe 实现   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把 ...

  7. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_05-SpringSecurityOauth2研究-搭建认证服务器

    3 Spring Security Oauth2研究 3.1 目标 本项目认证服务基于Spring Security Oauth2进行构建,并在其基础上作了一些扩展,采用JWT令牌机制,并自定 义了用 ...

  8. Spring Security 入门详解(转)

    1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别 处理 ...

  9. Spring Security 入门详解

    序:本文主要参考 spring实战 对里面的知识做一个梳理 1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完 ...

随机推荐

  1. 不想得手指关节炎?帮你提炼IDEA常用代码补全操作

    一.常用的代码补全操作 1..for和.fori(for 循环遍历) 输入args.for回车(args是一个数组或集合类),则会生成for循环遍历: 输入args.fori回车,则会生成带有索引的f ...

  2. PHP show_source() 函数

    实例 对测试文件("test.php")进行 PHP 语法高亮显示: <html><body><?phpshow_source("test. ...

  3. number类型转date类型

    遇到用数字记录日期时,进行查询转换. create or replace function num_to_date(s in number) return dateisbegin return to_ ...

  4. BSGS 学习笔记

    问题:求$a^x\equiv b\ (mod\ p)$的最小正整数解. 这时候就要用到BSGS(拔山盖世)算法.直接进入正题: 设$x=im-n$, 则原式等于$a^{im-n}\equiv b\ ( ...

  5. 【FZYZOJ】细菌 题解(最短路)

    题目描述 为了研究一种新型细菌(称它为S型细菌)的性质,Q博士将S型细菌放在了一个犹如迷宫一般的通道面前,迷宫中N个站点,每个站点之间以一种单向通道的形式连接,当然,也有可能某两个站点之间是互不联通的 ...

  6. 银弹谷零代码开发V百科|使用技巧:OMG!这些时间日期函数太好用了吧,盘它

    银弹谷零代码开发V百科|使用技巧:OMG!这些时间日期函数太好用了吧,盘它 Hello~everybody!小V又来咯!这次小V给大家带来的是零代码开发V平台常用的时间日期函数.小V知道我们平时常常会 ...

  7. 使用selenium再次爬取疫情数据(链接数据库)

    爬取网页地址: 丁香医生 数据库连接代码: def db_connect(): try: db=pymysql.connect('localhost','root','zzm666','payiqin ...

  8. node根据excel批量更名

    程序预览 index.js var xlsx = require('node-xlsx'); var fs = require('fs'); process.stdin.setEncoding('ut ...

  9. JS click延迟解决方案

    click延迟解决方案     移动端click事件会有300ms的延迟,原因是移动端屏幕双击会缩放页面 1.禁止缩放功能 浏览器禁用默认双击缩放行为去掉300ms的点击延迟 user-scalabl ...

  10. Django 环境下常用的模型设计

    Django 环境下常用的模型设计 用户表 继承 django.contrib.auth.model import AbstractUser AbstractUser 默认已经包含了很多字段了 id ...