spring|spring security oauth2--基于JDBC存储令牌
基于JDBC存储令牌
1、添加相关的数据库连接的依赖
com.zaxxer
HikariCP
3.4.2
org.springframework.boot
spring-boot-starter-jdbc
2.0.8.RELEASE
org.apache.tomcat
tomcat-jdbc
org.springframework.boot
spring-boot-starter-jdbc
2.1.7.RELEASE
mysql
mysql-connector-java
5.1.47
2、配置相关的数据库连接参数:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/spring_security_oauth2?useUnicode=true&useOldAliasMetadataBehavior=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username: root
password: root123hikari:
minimum-idle: 5
idle-timeout: 600000
maximum-pool-size: 10
auto-commit: true
max-lifetime: 1800000
pool-name: MyHikariCP
connection-timeout: 30000
connection-test-query: SELECT 1
注意(此为本人启动项目遇到的错误,没有遇到的请略过):
1、有些引入的jdbc的jar包不支持参数配置的格式为:spring.datasource.url,此时可以更改为spring.datasourc.jdbc-url
2、引入的mysql-connector-java的jar包可能与本地mysql版本冲突,出现BigInteger to Long 的错误,此时需要更换数据库连接的jar包版本。
3、需要在数据库中创建的相关数据表 相关sql从官网引入:https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
-- used in tests that use HSQL
create table oauth_client_details (
client_id VARCHAR(256) PRIMARY KEY,
resource_ids VARCHAR(256),
client_secret VARCHAR(256),
scope VARCHAR(256),
authorized_grant_types VARCHAR(256),
web_server_redirect_uri VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INTEGER,
refresh_token_validity INTEGER,
additional_information VARCHAR(4096),
autoapprove VARCHAR(256)
);
create table oauth_client_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256)
);
create table oauth_access_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256),
authentication LONGVARBINARY,
refresh_token VARCHAR(256)
);
create table oauth_refresh_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication LONGVARBINARY
);
create table oauth_code (
code VARCHAR(256), authentication LONGVARBINARY
);
create table oauth_approvals (
userId VARCHAR(256),
clientId VARCHAR(256),
scope VARCHAR(256),
status VARCHAR(10),
expiresAt TIMESTAMP,
lastModifiedAt TIMESTAMP
);
-- customized oauth_client_details table
create table ClientDetails (
appId VARCHAR(256) PRIMARY KEY,
resourceIds VARCHAR(256),
appSecret VARCHAR(256),
scope VARCHAR(256),
grantTypes VARCHAR(256),
redirectUrl VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INTEGER,
refresh_token_validity INTEGER,
additionalInformation VARCHAR(4096),
autoApproveScopes VARCHAR(256)
);
注意:
在mysql中没有LONGVARBINARY类型,此时需要将其替换为:blob类型。
4、更改认证服务器的客户端配置方式 由于现在需要使用JDBC存储令牌替换内存存储的方式,因此需要更改认证服务器的客户端配置方式,相关的更改如下:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}@Bean
public TokenStore tokenStore(){
return new JdbcTokenStore(dataSource());
}@Bean
public JdbcClientDetailsService jdbcClientDetailsService(){
return new JdbcClientDetailsService(dataSource());
}@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(jdbcClientDetailsService());
}@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore());
}
}
5、在数据库中添加客户端配置信息(client_id、secret、scope、authorizedGrantTypes、redirectUris)
文章图片
6、以下是进行登录相关操作
文章图片
文章图片
文章图片
文章图片
7、进行用户权限认证
认证:验证账户密码
授权:角色可以操作的数据
基于角色的访问控制(权限控制模型:论文,社区、RFC6749)
RBAC基于角色
ACL访问控制列表
ABAC基于属性
PBAC基于策略
我们选择使用的是RBAC模型(Role-Based Access Control)
基于角色的访问控制是实施面向企业安全策略的一种有效的访问控制方式,其基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合和权限集合之间建立一个角色集合。每一种角色对应一组相应的权限。一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。这样做的好处在于,不必每次创建用户都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户权限的变更要少的多,这样简化用户的权限管理,减少系统的开销。
RBAC又三个著名的安全原则:最小权限原则、责任分离原则、数据抽象原则。
Who 对What(Which)进行 How 操作:
Who:权限的拥有者或主体(User)
What:权限针对的对象或资源(静态资源:功能操作,数据列;动态资源:数据 文章,相册,笔记)
How:具体的权限(CRUD)
更多的详细信息请百度百科;
创建用户角色权限相关数据表
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`(
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`created_time` datetime(0) NULL DEFAULT NULL,
`updated_time` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'admin', '$2a$10$ydRx9xOGxmrZXqUTQ5iI8eSp/D.1V.1y469SAiYhMoMQ0TuBEVdr2', '18392023876', '364738383@qq.com', '2020-03-08 12:47:50', '2020-03-08 12:47:54');
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role`(
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(0) NULL DEFAULT NULL COMMENT '父角色',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色名称',
`ename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色英文名',
`description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色备注',
`created_time` datetime(0) NULL DEFAULT NULL,
`updated_time` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_role
-- ----------------------------
INSERT INTO `t_role` VALUES (1, 0, '超级管理员', 'admin', '超级管理员拥有所有的权限', '2020-03-08 12:49:19', '2020-03-08 12:49:22');
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for t_permission
-- ----------------------------
DROP TABLE IF EXISTS `t_permission`;
CREATE TABLE `t_permission`(
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(0) NULL DEFAULT NULL COMMENT '父权限',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限名称',
`ename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限英文名称',
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限路径',
`description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
`created_time` datetime(0) NOT NULL COMMENT '创建时间',
`updated_time` datetime(0) NOT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_permission
-- ----------------------------
INSERT INTO `t_permission` VALUES (1, 0, '系统管理', 'System', '/', NULL, '2020-03-08 12:35:49', '2020-03-08 12:35:52');
INSERT INTO `t_permission` VALUES (2, 1, '用户管理', 'SystemUser', '/users/', NULL, '2020-03-08 12:36:32', '2020-03-08 12:36:36');
INSERT INTO `t_permission` VALUES (3, 2, '查看用户', 'SystemUserView', NULL, NULL, '2020-03-08 12:37:34', '2020-03-08 12:37:37');
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for t_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `t_role_permission`;
CREATE TABLE `t_role_permission`(
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`role_id` bigint(0) NOT NULL,
`permission_id` bigint(0) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_role_permission
-- ----------------------------
INSERT INTO `t_role_permission` VALUES (1, 1, 1);
INSERT INTO `t_role_permission` VALUES (2, 1, 2);
INSERT INTO `t_role_permission` VALUES (3, 1, 3);
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role`(
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`user_id` bigint(0) NOT NULL,
`role_id` bigint(0) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user_role
-- ----------------------------
INSERT INTO `t_user_role` VALUES (1, 1, 1);
SET FOREIGN_KEY_CHECKS = 1;
8、使用mybatisCoderHelperPro插件生成相关的service,mapper,entity。
在application.yml种配置相关的扫描路径
mybatis:
type-aliases-package: com.tealala.oauth2.server.domain
mapper-locations: classpath:mapper/*.xml
9、生成UserDetailsService接口实现类MyUserDetailsService,更改用户鉴权类WebSercurityConfiguration
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private TUserService tUserService;
@Autowired
private TPermissionService tPermissionService;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
TUser user = tUserService.getByUsername(username);
List grantedAuthorities = Lists.newArrayList();
if(user != null){
List tPermissions = tPermissionService.findByUserId(user.getId());
for (TPermission tPermission : tPermissions) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(tPermission.getEname());
grantedAuthorities.add(grantedAuthority);
}}
return new User(user.getUsername(),user.getPassword(),grantedAuthorities);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled =true,jsr250Enabled = true)
public class WebSercurityConfiguration extends WebSecurityConfigurerAdapter {@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}@Bean
@Override
public UserDetailsService userDetailsService(){
return new MyUserDetailsService();
}@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}}
【spring|spring security oauth2--基于JDBC存储令牌】
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- spring|spring boot项目启动websocket
- Spring|Spring Boot 整合 Activiti6.0.0
- Spring集成|Spring集成 Mina
- springboot使用redis缓存
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- Spring|Spring Boot之ImportSelector