springsecurity-oauth2之基础知识介绍(一)

springsecurity-oauth2之基础知识介绍(一)

1.公钥与私钥

本项目采用JWT令牌生成采用非对称加密算法。

1.1 自己电脑上安装 Win64OpenSSL-1_1_1b.exe
1.2 找一个文件夹使用cmd命令打开dos命令窗口,输入:
 keytool -genkeypair -alias macrosoft -keyalg RSA -keypass 420188 -keystore macrosoft.jks -storepass 420188

解释:
-alias:密钥的别名
-keyalg:使用的hash算法
-keypass:密钥的访问密码(文件内容的读取密钥)
-keystore:密钥库文件名,macrosoft.jks保存了生成的证书
-storepass:密钥库的访问密码(即读取文件的密钥)

这样会生成一个密钥对的文件,叫 macrosoft.jks,它供认证服务器使用,现在要获取公钥供资源服务器使用。

1.3 获取公钥

在上面macrosoft.jks所在文件夹打开dos命令窗口,输入:

keytool -list -rfc --keystore macrosoft.jks | openssl x509 -inform pem -pubkey

会输入密钥库密码,即上面的storepass。 生成了公钥, 特别注意生成的公钥最后一个 - 但实际上是5个
粘的时候要加上。即:从-----BEGIN 开始到END PUBLIC KEY----- 结束。
把它粘贴到一行,放入public.key文件,并粘到资源服务器的resource目录下,和面好使用。

在这里插入图片描述

原理:认证服务器在生成token时会用到密钥对文件,即这里的
macrosoft.jks,资源服务器在解密的时候会用到公钥,即自己放入公钥的public.key文件。私钥加密,公钥解密。

2.关于资源服务器的认证

2.1 资源服务器的配置

资源服务器通过:RESOURCE_ID 和 scope来限制当前请求是否能访问本服务的。 Spring Security OAuth2
架构上分为Authorization Server认证服务器和Resource Server资源服务器。 我们可以为每一个Resource
Server(一个微服务实例)设置一个resourceid。Authorization Server给client第三方客户端授权的时候,
可以设置这个client可以访问哪一些Resource Server资源服务,如果没设置,就是对所有的Resource
Server都有访问权限。
在每个ResourceServer实例上设置resourceId,该resourceId作为该服务资源的唯一标识。(假如同一个微服务资源部署多份,resourceId相同)

 @Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {

    private static final String DEMO_RESOURCE_ID = "res1";
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(DEMO_RESOURCE_ID)
        //...... 还可以有有其他的配置
    }
 }
2.2 AuthorizationServer如何设置ResourceIDs?

在AuthorizationServer为客户端client配置ResourceID的目的是:限制某个client可以访问的资源服务

 @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    //配置客户端存储到db 代替原来得内存模式
    JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
    clientDetailsService.setPasswordEncoder(passwordEncoder);

登录的时候:

   headers.add("Authorization", getHttpBasic(clientId, clientSecret));
                    //4.组装最终请求参数
                    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
                    //5.发起登录请求接口
                    ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
 private String getHttpBasic(String clientId, String clientSecret) {
    String value = clientId + ":" + clientSecret;
    byte[] encode = Base64Utils.encode(value.getBytes(StandardCharsets.UTF_8));
    return "Basic " + new String(encode);
}

这里需要使用JdbcClientDetailsService类和数据库表oauth_client_details进行配置的持久化存储,以及动态配置

2.3 ResourceID在哪验证?

ResourceID当然是在Resource Server资源服务器进行验证(你能不能访问我的资源,当然由我自己来验证)。
当资源请求发送到Resource Server的时候会携带access_token,Resource
Server会根据access_token找到client_id,
进而找到该client可以访问的resource_ids。如果resource_ids包含ResourceServer自己设置ResourceID,这关就过去了,就可以继续进行其他的权限验证
在表:oauth_client_details的字段resource_ids可以配置多个资源名,表示当前这个clientId可以访问多个资源服务。例如:res1,res2
注意:
客户端在登录时可以传入clientId、clientSecret(线下给到客户端),那么这样就可以在oauth_client_details配置该clientId的访问资源服务器了,即resouce_ids的值
这里目(登录)前写死只有一个clientId、clientSecret(即c1和secret1),在oauth_client_details表中配置了c1对应的resource_ids字段的res1,res2,res3
也就是说资源服务器标识为res1或res2或res3的,clientId为c1的登录账号皆可访问

注意:这里资源服务器不仅仅是通过RESOURCE_ID来控制访问权限, 还通过scope来控制:

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

在oauth_client_details中对应的clientId、clientSecret对应的数据的字段scope必须包含当前资源服务器中的#oauth2.hasScope(‘ROLE_USER’)配置才能访问

3.sql文件准备

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `account` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '账号',
  `user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户密码',
  `last_login_time` datetime(0) NULL DEFAULT NULL COMMENT '上一次登录时间',
  `enabled` tinyint(1) NULL DEFAULT 1 COMMENT '账号是否可用。默认为1(可用)',
  `not_expired` tinyint(1) NULL DEFAULT 1 COMMENT '是否过期。默认为1(没有过期)',
  `account_not_locked` tinyint(1) NULL DEFAULT 1 COMMENT '账号是否锁定。默认为1(没有锁定)',
  `credentials_not_expired` tinyint(1) NULL DEFAULT 1 COMMENT '证书(密码)是否过期。默认为1(没有过期)',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
  `create_user` int(0) NULL DEFAULT NULL COMMENT '创建人',
  `update_user` int(0) NULL DEFAULT NULL COMMENT '修改人',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `user_name`(`user_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1507224801909940226 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_user_role_relation`;
CREATE TABLE `sys_user_role_relation`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_id` bigint(0) NULL DEFAULT NULL COMMENT '用户id',
  `role_id` bigint(0) NULL DEFAULT NULL COMMENT '角色id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1507224802006409218 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色关联关系表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_role_permission_relation`;
CREATE TABLE `sys_role_permission_relation`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `role_id` int(0) NULL DEFAULT NULL COMMENT '角色id',
  `permission_id` int(0) NULL DEFAULT NULL COMMENT '权限id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色-权限关联关系表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `role_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色名',
  `role_description` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色说明',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_request_path_permission_relation`;
CREATE TABLE `sys_request_path_permission_relation`  (
  `id` bigint(0) NULL DEFAULT NULL COMMENT '主键id',
  `url_id` int(0) NULL DEFAULT NULL COMMENT '请求路径id',
  `permission_id` int(0) NULL DEFAULT NULL COMMENT '权限id'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '路径权限关联表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_request_path`;
CREATE TABLE `sys_request_path`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `url` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '请求路径',
  `description` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路径描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '请求路径' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `permission_code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限code',
  `permission_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限名',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '权限表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code`  (
  `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authentication` blob NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

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(0) NULL DEFAULT NULL,
  `refresh_token_validity` int(0) 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(0) NULL DEFAULT NULL,
  `trusted` tinyint(0) 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;
SET FOREIGN_KEY_CHECKS = 1;

4.认证流程图

在这里插入图片描述
这里的认证服务就是我的macro-auth,网关就是我的macro-gateway,其他的都可以成为资源服务

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神雕大侠mu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值