使用篇二SpringBoot集成SpringSecurity(22)

Posted myitnews

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用篇二SpringBoot集成SpringSecurity(22)相关的知识,希望对你有一定的参考价值。

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` int(11) NOT NULL,
  `u_username` varchar(255) DEFAULT NULL,
  `u_password` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

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

-- 填充测试数据
insert into user values(1, admin, 123456);
insert into role values(1, 超级管理员),(2, 普通用户);
insert into user_role values(1,1,1),(2,1,2);

对应的实体类如下:

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)的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot,使用编码密码实现登录

Databinding使用篇二

结合 DispatcherServlet、ContextLoaderListener 和 SpringSecurity

如何在 Spring Boot 中在 Spring Security 级别启用 CORS [关闭]

Jquery学习之基础篇二

Vue实战篇二十四:分页显示