• (二)SpringCloud+Security+Oauth2 微服务初步集成


    一 引言

    本文主要好介绍了SpringCloud+Security+Oauth2 的初步集成,项目源码地址oauth2.0集成案例,以下案例主要是核心源码的解释,案例源码请查看案例源码

    二 项目结构说明

    在这里插入图片描述
    oauth-server oauth认证中心
    oauth-client oauth客户端
    oauth-nacos 注册中心和配置中心
    oauth-common 公用组件

    三 认证中心的搭建

    Oauth2提供了AuthorizationServerConfigurerAdapter适配器类来作为认证授权服务的配置,其中有三个方法源码如下:

    public class AuthorizationServerConfigurerAdapter  {
        //客户端详情:配置客户端请求的参数
    	public void configure(ClientDetailsServiceConfigurer clients)...	
    	//授权服务断点:配置授权码和令牌的管理/存储方式
    	public void configure(AuthorizationServerEndpointsConfigurer endpoints)...
        //授权服务安全配置:配置哪些路径放行(检查token的路径要放行)
    	public void configure(AuthorizationServerSecurityConfigurer security) ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    配置详解:

    • ClientDetailsServiceConfigurer :用来配置客户端详情服务:如配置客户端id(client_id)资源id、客户端密钥(secrect)、授权方式、scope等,可以基于内存或jdbc。(可以理解为是对浏览器向授权服务器获取授权码或令牌时需要提交的参数配置),如果你做过三方登录应该就能理解这些参数,其实就是对客户端的参数配置,在客户端获取授权码或者获取Token的URL请求中就需要带上这些客户端参数
    • AuthorizationServerEndpointsConfigurer:配置令牌的访问端点url和令牌服务,如配置如何管理授权码(内存或jdbc),如何管理令牌(存储方式,有效时间等等)
    • AuthorizationServerSecurityConfigurer: 用来配置令牌端点的安全约束,如配置对获取授权码,检查token等某些路径进行放行

    3.1 认证中心搭建

    @Configuration
    @EnableAuthorizationServer // 开启认证服务
    public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
        // 数据源
        @Autowired
        private DataSource dataSource;
        @Autowired
        private TokenStore tokenStore;
    
        @Autowired
        private AuthenticationManager authenticationManager;
        // 客户端配置
        @Bean
        public ClientDetailsService customClientDetailsService(){
            return new JdbcClientDetailsService(dataSource);
        }
    
    
    
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            /**
             * 必须将secret加密后存入数据库,否则报错:Encoded password does not look like BCrypt
             */
            clients.withClientDetails(customClientDetailsService());
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
            oauthServer
            		//对应/oauth/token_key 公开,获取公钥需要访问该端点
            		.tokenKeyAccess("permitAll()")
            		//对应/oauth/check_token ,路径需要授权,校验Token需要请求该端点
                    .checkTokenAccess("isAuthenticated()")
                    //允许客户端进行表单身份验证,使用表单认证申请令牌
                    .allowFormAuthenticationForClients();
        }
    
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenStore(tokenStore);
            endpoints.authenticationManager(authenticationManager);
            DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setTokenStore(endpoints.getTokenStore());
            tokenServices.setSupportRefreshToken(true);
            tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
            tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
            tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30));
            endpoints.tokenServices(tokenServices);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    配置详解:
    配置类上贴注解@EnableAuthorizationServer开启授权服务配置,继承AuthorizationServerConfigurerAdapter 实现配置的增强配置
    客户端详情配置
    JdbcClientDetailsService默认会去找数据库中的 名字为oauth_client_details 表中的数据作为客户端详情的配置,见 JdbcClientDetailsService类的源代码,所以我们需要在数据库执行以下sql创建表:并填充好数据

    DROP TABLE IF EXISTS `oauth_client_details`;
    CREATE TABLE `oauth_client_details` (
      `client_id` varchar(48) NOT NULL,
      `resource_ids` varchar(256) DEFAULT NULL,
      `client_secret` varchar(256) DEFAULT NULL,
      `scope` varchar(256) DEFAULT NULL,
      `authorized_grant_types` varchar(256) DEFAULT NULL,
      `web_server_redirect_uri` varchar(256) DEFAULT NULL,
      `authorities` varchar(256) DEFAULT NULL,
      `access_token_validity` int(11) DEFAULT NULL,
      `refresh_token_validity` int(11) DEFAULT NULL,
      `additional_information` varchar(4096) DEFAULT NULL,
      `autoapprove` varchar(256) DEFAULT NULL,
      PRIMARY KEY (`client_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    授权服务配置
    主要是通过AuthorizationServerEndpointsConfigurer 配置授权码和令牌相关的服务 ,在上面的配置类基础上增加配置内容

    AuthenticationManager认证管理器“password”模式会用到认证管理器,它是在Security配置中定义的

    TokenStore : token存储方式该接口常用的实现有:InMemoryTokenStore基于存储的token存储方案,JdbcTokenStore基于数据库的token存储方案,JwtToeknStore基于JWT的存储方案,RedisTokenStore基于Redis的存储方案,我上面的案例采用的是Redis的方式来实现

    AuthorizationServerTokenServices 该接口用来配置授权服务器令牌,如配置是否支持Token,Token的存储方式(内 存,jdbc,),token加密,token过期等

    令牌端点安全配置
    AuthorizationServerSecurityConfigurer:用来配置令牌端点的安全策略

    3.2 加载用户数据

    在面的Security中我们已经介绍了UserDetailsService 在进行用户认证的时候回调用该接口获得用户信息,实现改接口,根据用户名校验当前用户是否存在

    @Component
    public class UserDetailServiceImpl implements UserDetailsService {
    
        @Autowired
        BCryptPasswordEncoder passwordEncoder;
    
        @Autowired
        private RemoteUserService remoteUserService;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // 查询数据库 获得相应的用户
            PtUser ptUser = remoteUserService.findOneByAccount(username);
            if (ptUser==null){
                throw new UsernameNotFoundException("用户名或密码错误");
            }
            // todo 查询相应的角色 这里不做演示
            return new User(ptUser.getAccount(),ptUser.getPassword(), AuthorityUtils.NO_AUTHORITIES);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.3 采用密码模式 获取token

    http://localhost:9527/oauth/token?client_id=clientApp&client_secret=secretApp&grant_type=password&username=sys&password=123456
    
    • 1

    在这里插入图片描述

    四 客户端搭建

    4.1 客户端配置

    通过@EnableResourceServer开启客户端配置,继承ResourceServerConfigurerAdapter开启对客户端的增强配置

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        @Autowired
        private TokenStore tokenStore;
    
        @Autowired
        private ResourceServerTokenServices resourceServerTokenServices;
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.tokenStore(tokenStore);
            resources.tokenServices(resourceServerTokenServices);
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/user/**").permitAll()// 放行用户相关的接口
                    .anyRequest().authenticated();// 其他接口需要鉴权
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    配置说明:
    ResourceServerSecurityConfigurer 主要用于客户端关于oauth相关配置

    • ResourceServerTokenServices 用于客户端token的校验,当用户携带token请求资源时,资源服务器会向认证中心发送请求校验token的正确性,并把用户信息加载到安全上下文中
    • TokenStore 用于配置token的解析

    HttpSecurity 主要是对SpringSecurity中的相关配置

    4.2 yml配置token校验的相关配置

    security:
      oauth2:
        client:
          client-id: clientApp # oauth 分发的client-id
          client-secret: secretApp # oauth 分发的client-secret
        resource:
          token-info-uri: http://localhost:9527/oauth/check_token # 认证中心token校验
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.3 测试

    通过上面获得的token我们去访问资源服务器的相关资源
    携带token请求成功
    在这里插入图片描述
    不携带token,请求失败
    在这里插入图片描述
    由此Spring Security+oauth2.0简单搭建由此集成了

  • 相关阅读:
    【数据结构】带头双向循环链表的实现(C语言)
    分片集群-Sharded Cluster
    【华为OD机试真题 JS】一种字符串压缩表示的解压
    第10集丨龙场悟道:阳明心学的诞生
    程序分析与优化 - 5 指针分析
    几张高度概括电阻、电容、电感与磁珠的思维导图(高清原图)
    Qt音乐播放器
    echarts重叠柱状图(非堆叠柱状图)
    Golang基本的网络编程
    模板方法模式在交易策略开发中的应用
  • 原文地址:https://blog.csdn.net/Instanceztt/article/details/128187984