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: 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包版本。

 

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、以下是进行登录相关操作

spring security oauth2--基于JDBC存储令牌_第1张图片

spring security oauth2--基于JDBC存储令牌_第2张图片

 

spring security oauth2--基于JDBC存储令牌_第3张图片

 

 

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', '[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;

 

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 security oauth2--基于JDBC存储令牌)