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
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: root123
hikari:
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包版本。
相关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类型。
由于现在需要使用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());
}
}
认证:验证账户密码
授权:角色可以操作的数据
基于角色的访问控制(权限控制模型:论文,社区、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', '[email protected]', '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;
在application.yml种配置相关的扫描路径
mybatis:
type-aliases-package: com.tealala.oauth2.server.domain
mapper-locations: classpath:mapper/*.xml
@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());
}
}