SpringSecurity是专门针对基于Spring项目的安全框架,充分利用了依赖注入和AOP来实现安全管控。在很多大型企业级系统中权限是最核心的部分,一个系统的好与坏全都在于权限管控是否灵活,是否颗粒化。在早期的SpringSecurity版本中我们需要大量的xml来进行配置,而基于SpringBoot整合SpringSecurity框架相对而言简直就是太简单了。

SpringSecurity框架有两个概念认证和授权,认证可以访问系统的用户,而授权则是用户可以访问的资源。

1. 构建项目

加入JPA、Security、Druid、MySQL等依赖,如下图:

<dependencies>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--spring data jpa-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!--druid数据源-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.20</version>
    </dependency>
    <!-- fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
    <!--spring-security-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!--test-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

2. application.yml

server:
  port: 8080

#数据源
spring:
  datasource:
    url: jdbc:mysql://192.168.178.5:12345/cloudDB01?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    #指定使用的数据库连接池
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      #初始化数量
      initial-size: 8
      min-idle: 1
      #最大活跃数
      max-active: 20
      #最大连接等到超时时间
      max-wait: 60000
      time-between-eviction-runsMillis: 60000
      min-evictable-idle-timeMillis: 300000
      validation-query: select 'x' FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      #打开PSCache,并且指定每个连接PSCache的大小
      pool-prepared-statements: true
      max-open-prepared-statements: 20
      max-pool-prepared-statement-per-connection-size: 20
      #配置监控统计拦截的filters,去掉后监控界面的sql将无法统计,wall用于防火墙
      filters: stat
      #通过connectionProperties属性来打开mergeSql功能;慢sql记录
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      use-global-data-source-stat: true
  jpa:
    database: MySQL
    show-sql: true
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

3. 用户表、角色表、用户角色关联表

-- 用户表
CREATE TABLE `user` (
  `u_id` ) NOT NULL,
  `u_username` ) DEFAULT NULL,
  `u_password` ) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 角色表
CREATE TABLE `role` (
  `r_id` ) NOT NULL,
  `r_name` ) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 用户-角色表
CREATE TABLE `user_role` (
  `ur_id` ) NOT NULL,
  `ur_user_id` ) DEFAULT NULL,
  `ur_role_id` ) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 填充测试数据
, ');
, , '普通用户');
,,),(,,);

对应的实体类如下:

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Entity
@Table(name = "user")
public class UserDTO implements Serializable, UserDetails {

    @Id
    @Column(name = "u_id")
    private Integer id;
    @Column(name = "u_username")
    private String userName;
    @Column(name = "password")
    private String password;

    @ManyToMany
    @JoinTable(name = "user_role",
            joinColumns = {@JoinColumn(name = "ur_user_id")},
            inverseJoinColumns = {@JoinColumn(name = "ur_role_id")})
    private List<RoleDTO> roles;

    public UserDTO(String username, String password, List<RoleDTO> roles) {
        this.userName = username;
        this.password = password;
        this.roles = roles;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (RoleDTO role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }
        return authorities;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String getPassword() {
        return password;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String getUsername() {
        return userName;
    }

    // 帐户是否过期
    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    // 帐户是否被冻结
    @Override
    public boolean isAccountNonLocked() {
        return false;
    }
    // 帐户密码是否过期,一般有的密码要求性高的系统会使用到,比较每隔一段时间就要求用户重置密码
    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }
    // 帐号是否可用
    @Override
    public boolean isEnabled() {
        return false;
    }
}
@Entity
@Table(name = "role")
public class RoleDTO {
    @Id
    @Column(name = "r_id")
    private Integer id;
    @Column(name = "r_name")
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

UserDetails是SpringSecurity验证框架内部提供的用户验证接口,我们需要实现getAuthorities方法内容,将我们定义的角色列表添加到授权的列表内。可以看到我们的用户实体内添加了对角色的列表支持,并添加了@ManyToMany的关系注解。我们查询用户时SpringDataJPA会自动查询处关联表user_roles对应用户的角色列表放置到名叫roles的List集合内。

4. 配置JPA访问数据

【使用篇二】SpringBoot集成SpringSecurity(22)的更多相关文章

  1. SpringBoot 集成SpringSecurity JWT

    目录 1. 简介 1.1 SpringSecurity 1.2 OAuth2 1.3 JWT 2. SpringBoot 集成 SpringSecurity 2.1 导入Spring Security ...

  2. (转)SpringBoot非官方教程 | 第十二篇:springboot集成apidoc

    首先声明下,apidoc是基于注释来生成文档的,它不基于任何框架,而且支持大多数编程语言,为了springboot系列的完整性,所以标了个题. 一.apidoc简介 apidoc通过在你代码的注释来生 ...

  3. SpringBoot非官方教程 | 第十二篇:springboot集成apidoc

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-apidoc/ 本文出自方志朋的博客 首先声明下 ...

  4. SpringBoot非官方教程 | 第十三篇:springboot集成spring cache

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot13-springcache/ 本文出自方志朋的博 ...

  5. (转)第十一篇:springboot集成swagger2,构建优雅的Restful API

    声明:本部分内容均转自于方志明博友的博客,因为本人很喜欢他的博客,所以一直在学习,转载仅是记录和分享,若也有喜欢的人的话,可以去他的博客首页看:http://blog.csdn.net/forezp/ ...

  6. (转) SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API

    swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅 ...

  7. SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-swagger2/ 本文出自方志朋的博客 swa ...

  8. Spring Boot笔记(二) springboot 集成 SMTP 发送邮件

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 笔记:乘着项目迭代的间隙,把一些可复用的功能从项目中抽取出来,这是其中之一, 一.添加SMTP 及 MA ...

  9. Springboot集成SpringSecurity

    一.Spring security 是什么? Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架. 它提供了一组可以在Spring应用上 ...

随机推荐

  1. 【JS】332- 为什么我更喜欢对象而不是 switch 语句

    昨天偷懒了,欢迎点击关注???这样我就多更大的动力日更了- 正文从这里开始~~~ 最近(或者不是最近,这完全取决于您什么时候阅读这边文章),我正在跟我的团队伙伴讨论如何去处理这种需要根据不同的值去处理 ...

  2. DS-5获取License

    1.点击Eclipse for DS-5,打开DS-5,弹出workspace选择窗口   2.点击OK,打开DS-5,弹出License窗口,license需要自己去解决

  3. poj 1679 The Unique MST (次小生成树模板题)

    Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...

  4. 酷狗音乐API接口大全(40+个)

    歌单分类部分 获取精选专区所有分类 http://mobilecdnbj.kugou.com/api/v3/tag/list?pid=0&apiver=2&plat=0 获取热门推荐分 ...

  5. 【搞定Jvm面试】 面试官:谈谈 JVM 类加载过程是怎样的?

    类加载过程 Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢? 系统加载 Class 类型的文件主要三步:加载->连接->初始化.连接过程 ...

  6. C++ 构造函数【新手必学】

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:可乐司机构造函数是C++里面的基础内容,特别重要,如果你刚学C++不久, ...

  7. CefSharp禁止弹出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接

    说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接 gi ...

  8. 使用docker运行dotnetcore站点

    使用docker运行netcore站点 1.新建一.netcore测试站点,dotnet publish 发布到publish目录下 2.编写Dockerfile文件 3.打包上传到centos服务器 ...

  9. 2.Android-sdk目录介绍、ADT使用介绍、创建helloworld

    1.android中常用名词介绍 ADT:  ADT为Eclipse的插件.为Eclipse和SDK之间起了一个桥梁的作用. SDK: 软件开发工具包(Soft Development Kit),它为 ...

  10. python程序员面试高概率会遇到的技术问题

    本篇只列举会问到的技术问题.其他的问题会在另一篇文章多年职场老狗的面试经验提到. 1. TCP三次握手和四次挥手的过程 2.HTTP协议的状态码 3.讲一下自己用过的设计模式 4.python的多线程 ...