权限-将授权码和客服端改为数据库的方式(八)

完善环境配置

上篇文章中客户端信息和授权码仍然存储在内存中,生产环境中通过会存储在数据库中,下边完善环境的配置:

创建表

下面这两个数据库的结构都是OAuth2 默认使用的,我们只需要操作一些方法就可以操作这两个数据库(详情见下面步骤)

DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘客户端标 识‘,
  `resource_ids` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘接入资源列表‘,
  `client_secret` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端秘钥‘,
  `scope` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorized_grant_types` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `web_server_redirect_uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorities` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `access_token_validity` int(11) NULL DEFAULT NULL,
  `refresh_token_validity` int(11) NULL DEFAULT NULL,
  `additional_information` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  `archived` tinyint(4) NULL DEFAULT NULL,
  `trusted` tinyint(4) NULL DEFAULT NULL,
  `autoapprove` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘接入客户端信息‘ ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of oauth_client_details
--  下面的加密字符串原来的值是secret
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES (‘c1‘, ‘res1‘, ‘$2a$10$NlBC84MVb7F95EXYTXwLneXgCca6/GipyWR5NHm8K0203bSQMLpvm‘, ‘ROLE_ADMIN,ROLE_USER,ROLE_API‘, ‘client_credentials,password,authorization_code,implicit,refresh_token‘, ‘http://www.baidu.com‘, NULL, 7200, 259200, NULL, ‘2019‐09‐09 16:04:28‘, 0, 0, ‘false‘); INSERT INTO `oauth_client_details` VALUES (‘c2‘, ‘res2‘, ‘$2a$10$NlBC84MVb7F95EXYTXwLneXgCca6/GipyWR5NHm8K0203bSQMLpvm‘, ‘ROLE_API‘, ‘client_credentials,password,authorization_code,implicit,refresh_token‘, ‘http://www.baidu.com‘, NULL, 31536000, 2592000, NULL, ‘2019‐09‐09 21:48:51‘, 0, 0, ‘false‘);
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code` 
( 
    `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 		`authentication` blob NULL, INDEX `code_index`(`code`) USING BTREE 
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

将客服端信息存储到内存

修改uaa模块下的AuthorizationServer类

    //新增密码加密
	@Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //新增:我们将客服端的信息存储到数据库
    @Bean
    public ClientDetailsService clientDetailsService(DataSource dataSource) {
        ClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
        ((JdbcClientDetailsService) clientDetailsService).setPasswordEncoder(passwordEncoder());
        return clientDetailsService;
    }
	//修改客服端配置为:
    @Override
    public void configure(ClientDetailsServiceConfigurer client) throws Exception {
        client.withClientDetails(clientDetailsService);
    }

将授权码存储到内存

//    @Bean
////    public AuthorizationCodeServices authorizationCodeServices() {
////        return new InMemoryAuthorizationCodeServices();
////    }
    //内存的方式改为数据库的方式
    @Bean
    public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {
        return new JdbcAuthorizationCodeServices(dataSource);
    }

测试

运行uaa和order

密码模式访问

http://localhost:9001/uaa/oauth/token?client_id=c1&client_secret=secret&grant_type=password&redirect_uri=http://www.baidu.com&username=dong&password=123456

权限-将授权码和客服端改为数据库的方式(八)

结果

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzMSJdLCJ1c2VyX25hbWUiOiJkb25nIiwic2NvcGUiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiIsIlJPTEVfQVBJIl0sImV4cCI6MTYyMDg4MDU0OSwiYXV0aG9yaXRpZXMiOlsicDEiLCJwMiJdLCJqdGkiOiI4MmFlMjVlOS0xODhhLTQ1ZjItOGJhNi1mZWJiY2FhN2UwYmQiLCJjbGllbnRfaWQiOiJjMSJ9.7vS_q-paZOxsw32UP7-Lvweo5pFVTAqsbhHgGQg3w2o",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzMSJdLCJ1c2VyX25hbWUiOiJkb25nIiwic2NvcGUiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiIsIlJPTEVfQVBJIl0sImF0aSI6IjgyYWUyNWU5LTE4OGEtNDVmMi04YmE2LWZlYmJjYWE3ZTBiZCIsImV4cCI6MTYyMTEzMjU0OSwiYXV0aG9yaXRpZXMiOlsicDEiLCJwMiJdLCJqdGkiOiIxNDIwZjk5Mi00MzQ4LTQzNGEtODAzZC05OTY1MDY4Y2M5MTQiLCJjbGllbnRfaWQiOiJjMSJ9.cSUl1_HrdaEz8pi3K9eFS-q6aVFXD5fjih5kBaPpGrE",
    "expires_in": 7199,
    "scope": "ROLE_ADMIN ROLE_USER ROLE_API",
    "jti": "82ae25e9-188a-45f2-8ba6-febbcaa7e0bd"
}

访问:http://localhost:9001/uaa/oauth/check_token来校验一下令牌的合法性

权限-将授权码和客服端改为数据库的方式(八)

结果

{
    "aud": [
        "res1"
    ],
    "user_name": "dong",
    "scope": [
        "ROLE_ADMIN",
        "ROLE_USER",
        "ROLE_API"
    ],
    "exp": 1620880549,
    "authorities": [
        "p1",
        "p2"
    ],
    "jti": "82ae25e9-188a-45f2-8ba6-febbcaa7e0bd",
    "client_id": "c1"
}

我们发现scope等属性和数据库的属性是一样的,这说明我们改为数据库的方式成功了

权限-将授权码和客服端改为数据库的方式(八)f

生成授权码 scope改为上面从数据库中读取的任意一个如:ROLE_ADMIN

localhost:9001/uaa/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com

访问上面的地址:首先需要登录 dong 123456

然后授权获取授权码

权限-将授权码和客服端改为数据库的方式(八)

获取的授权码如下

权限-将授权码和客服端改为数据库的方式(八)

我们去看数据库oauth_code,发现授权码也成功保存的数据库中了

权限-将授权码和客服端改为数据库的方式(八)

然后我们把order的ResourceServerConfig类安全拦截的scope改为ROLE_ADMIN

 @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/**")
                .access("#oauth2.hasScope(‘ROLE_ADMIN‘)")
                .and()
                .csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

然后运行order,访问:http://localhost:9002/order/r1等资源就可以成功了(注意要把token带上)

权限-将授权码和客服端改为数据库的方式(八)

结果

访问资源1

参考教程 黑马

权限-将授权码和客服端改为数据库的方式(八)

上一篇:Can't connect to local MySQL server through socket 解决方案


下一篇:MongoDB如何才能优雅且合理地设计?