使用篇二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)的主要内容,如果未能解决你的问题,请参考以下文章
结合 DispatcherServlet、ContextLoaderListener 和 SpringSecurity