美文网首页
OAuth2.0-完善环境配置

OAuth2.0-完善环境配置

作者: Doooook | 来源:发表于2020-12-20 19:00 被阅读0次

    截止目前客户端信息和授权码仍然存储在内存中,生产环境中通常会存储在数据库中,下边将完善环境的配置。

    一、创建表

    1、接入客户端信息表 oauth_client_details

    CREATE TABLE `oauth_client_details` (
      `client_id` varchar(255) COLLATE utf8_croatian_ci NOT NULL COMMENT '客户端标识',
      `resource_ids` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL COMMENT '接入资源列表',
      `client_secret` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL COMMENT '客户端秘钥',
      `scope` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      `authorized_grant_types` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      `web_server_redirect_uri` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      `authorities` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      `access_token_validity` int(11) DEFAULT NULL,
      `refresh_token_validity` int(11) DEFAULT NULL,
      `additional_information` longtext COLLATE utf8_croatian_ci,
      `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `archived` tinyint(4) DEFAULT NULL,
      `trusted` tinyint(4) DEFAULT NULL,
      `autoapprove` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      PRIMARY KEY (`client_id`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_croatian_ci ROW_FORMAT=DYNAMIC COMMENT='接入客户端信息';
    
    -- 初始化数据
    INSERT INTO oauth2.oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, create_time, archived, trusted, autoapprove) VALUES ('c1', 'res1', '$2a$10$iDXj8iLaUNVZoJ2M5xkkb./o25cvWpNvB6cqmDBBeiRcDOBCnSf/.', 'ROLE_ADMIN,ROLE_USER,ROLE_API', 'client_credentials,password,authorization_code,implicit,refresh_token', 'http://www.baidu.com', null, 7200, 259200, null, '2019-12-08 09:55:11', 0, 0, 'false');
    INSERT INTO oauth2.oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, create_time, archived, trusted, autoapprove) VALUES ('c2', 'res2', '$2a$10$iDXj8iLaUNVZoJ2M5xkkb./o25cvWpNvB6cqmDBBeiRcDOBCnSf/.', 'ROLE_API', 'client_credentials,password,authorization_code,implicit,refresh_token', 'http://www.baidu.com', null, 3153600, 25920000, null, '2019-09-09 21:48:51', 0, 0, 'false');
    

    2、授权码表 oauth_code Spring Security OAuth2使用,用来存储授权码

    CREATE TABLE `oauth_code` (
      `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `code` varchar(255) COLLATE utf8_croatian_ci DEFAULT NULL,
      `authentication` blob,
      KEY `code_index` (`code`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_croatian_ci ROW_FORMAT=COMPACT;
    

    二、配置权限服务

    1、修改AuthorizationServer
    ClientDetailsServiceAuthorizationCodeServices从数据库中读取数据。

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    
        /**
         * 在 TokenConfig 中已经注入
         */
        @Autowired
        private TokenStore tokenStore;
    
        @Autowired
        private ClientDetailsService clientDetailsService;
    
        /**
         * 本类中注入
         */
        @Autowired
        private AuthorizationCodeServices authorizationCodeServices;
    
        /**
         * 在 WebSecurityConfig 中已经注入
         */
        @Autowired
        private AuthenticationManager authenticationManager;
    
        /**
         * 在 TokenConfig 中已经注入
         */
        @Autowired
        private JwtAccessTokenConverter accessTokenConverter;
    
        /**
         * 在 WebSecurityConfig 中已经注入
         */
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        /**
         * 将客户端信息存储到数据库
         * @param dataSource
         * @return
         */
        @Bean
        public ClientDetailsService clientDetailsService(DataSource dataSource) {
            JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
            clientDetailsService.setPasswordEncoder(passwordEncoder);
            return clientDetailsService;
        }
    
        /**
         * 将客户端信息存储到内存中
         * @return ClientDetailsService
         */
        /*@Bean
        public ClientDetailsService clientDetailsService() {
            return new InMemoryClientDetailsService();
        }*/
    
        /**
         * 配置客户端详情信息服务
         * @param clients
         * @throws Exception
         */
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    
            // clientDetailsService使用jdbc查询数据库的方式
            clients.withClientDetails(clientDetailsService);
    
            // 使用in-memory存储
            /*clients.inMemory()
                    // client_id
                    .withClient("c1")
                    // 客户端秘钥
                    .secret(new BCryptPasswordEncoder().encode("secret"))
                    // 客户端可以访问的资源列表
                    .resourceIds("res1")
                    // 该client允许的授权范围(所有支持的5种)
                    .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
                    // 允许的授权范围(客户端的权限),user-service、read等标识
                    .scopes("all")
                    // false:授权码模式,跳转到授权的页面,如果是true,不用跳转页面
                    .autoApprove(false)
                    // 加上验证回调地址
                    .redirectUris("http://www.baidu.com");*/
                    // 另外一套
                    // .and()
                    // // client_id
                    // .withClient("c1")
                    // // 客户端秘钥
                    // .secret(new BCryptPasswordEncoder().encode("secret"))
                    // // 客户端可以访问的资源列表
                    // .resourceIds("res1")
                    // // 该client允许的授权范围(所有支持的5种)
                    // .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
                    // // 允许的授权范围(客户端的权限),user-service、read等标识
                    // .scopes("all")
                    // // false:授权码模式,跳转到授权的页面,如果是true,不用跳转页面
                    // .autoApprove(false)
                    // // 加上验证回调地址
                    // .redirectUris("http://www.baidu.com");
    
        }
    
        /**
         * 令牌管理服务
         * @return
         */
        @Bean
        public AuthorizationServerTokenServices tokenService() {
            DefaultTokenServices service = new DefaultTokenServices();
            // 客户端详情服务
            service.setClientDetailsService(clientDetailsService);
            // 是否产生支持刷新令牌
            service.setSupportRefreshToken(true);
            // 令牌存储策略
            service.setTokenStore(tokenStore);
    
            // 设置令牌增强
            TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
            tokenEnhancerChain.setTokenEnhancers(Collections.singletonList(accessTokenConverter));
            service.setTokenEnhancer(tokenEnhancerChain);
    
            // 令牌桶默认有效期2小时
            service.setAccessTokenValiditySeconds(7200);
            // 刷新令牌默认有效期3天
            service.setRefreshTokenValiditySeconds(259200);
            return service;
        }
    
        /**
         * 令牌端点的安全配置
         * @param security
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            // /oauth/token_key: 这个endpoint当使用jwttoken且使用非对称加密时,资源服务器用于获取公钥而开放的,这里指这个endpoint完全公开
            security.tokenKeyAccess("permitAll()")
                    // oauth/check_token: checkToken这个endpoint完全公开
                    .checkTokenAccess("permitAll()")
                    // 允许表单认证
                    .allowFormAuthenticationForClients();
        }
    
        /**
         * 设置授权码模式的授权码如何存取,暂时采用内存方式
         * @return
         */
        /*@Bean
        public AuthorizationCodeServices authorizationCodeServices() {
            // 内存方式
            return new InMemoryAuthorizationCodeServices();
        }*/
    
        @Bean
        public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {
            // 设置授权码模式的授权码如何存储:数据库方式
            return new JdbcAuthorizationCodeServices(dataSource);
        }
    
        /**
         * 令牌访问端点
         * tokenService():令牌管理服务
         * @param endpoints
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            // authenticationManager:认证管理器,密码模式
            // authorizationCodeServices:授权码服务
            endpoints.authenticationManager(authenticationManager)
                    .authorizationCodeServices(authorizationCodeServices)
                    // 令牌管理服务,都需要
                    .tokenServices(tokenService())
                    // 允许的POST提交
                    .allowedTokenEndpointRequestMethods(HttpMethod.POST);
        }
    }
    
    授权获取JWT令牌 校验JWT令牌

    浏览器访问:http://127.0.0.1:53020/uaa/oauth/authorize?client_id=c1&response_type=code&redirect_uri=http://www.baidu.com,如果没有指定scope,默认就是全部的scope,如果指定具体的scope则为http://127.0.0.1:53020/uaa/oauth/authorize?client_id=c1&scope=ROLE_API&response_type=code&redirect_uri=http://www.baidu.com如下:

    指定scope授权 自动重定向到登录页面 授权页面 授权码 通过授权码获取token 验证token

    相关文章

      网友评论

          本文标题:OAuth2.0-完善环境配置

          本文链接:https://www.haomeiwen.com/subject/onyknktx.html