Oauth找不到/user/me在哪实现

提问:哎,怪我太菜。找不到/user/me在哪实现。(这里的9091就是该项目自己的端口)。各位大老指条明路。

img

img

img

  • 这篇博客: 微服务商城系统(十一)权限控制、OAuth 动态加载数据中的 一、资源服务器授权配置 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 在这里插入图片描述
         基本上所有微服务都是资源服务。
    (1)用户微服务
        首先,认证服务使用私钥,采用非对称加密算法 生成令牌,资源服务使用公钥 来校验令牌的合法性。 需要配置公钥,并将公钥拷贝到 public.key 文件中,将此文件拷贝到每一个需要的资源服务工程的 classpath 下 ,比如 用户微服务:
    在这里插入图片描述
    解析令牌需要添加依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    

        接下来,需要配置每个系统的 Http 请求路径安全控制策略 以及 读取公钥信息识别令牌,对于用户微服务,新建 config 包,提供配置类,@EnableResourceServer 注解用于开启资源校验服务,进行令牌的校验;@EnableGlobalMethodSecurity 注解是全局方法校验:

    @Configuration
    @EnableResourceServer
    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的PreAuthorize注解
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        //公钥
        private static final String PUBLIC_KEY = "public.key";
    
        /***
         * 定义 JwtTokenStore
         * @param jwtAccessTokenConverter
         * @return
         */
        @Bean
        public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
            return new JwtTokenStore(jwtAccessTokenConverter);
        }
    
        /***
         * 定义 JJwtAccessTokenConverter
         * @return
         */
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setVerifierKey(getPubKey());
            return converter;
        }
        /**
         * 获取非对称加密公钥 Key
         * @return 公钥 Key
         */
        private String getPubKey() {
            Resource resource = new ClassPathResource(PUBLIC_KEY);
            try {
                InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
                BufferedReader br = new BufferedReader(inputStreamReader);
                return br.lines().collect(Collectors.joining("\n"));
            } catch (IOException ioe) {
                return null;
            }
        }
    
        /***
         * Http 安全配置,对每个到达系统的 http 请求链接进行校验
         * @param http
         * @throws Exception
         */
        @Override
        public void configure(HttpSecurity http) throws Exception {
            // 所有请求必须认证通过
            http.authorizeRequests()
                    // 下边的路径放行
                    .antMatchers(
                            "/user/add"). //配置地址放行
                    permitAll()
                    .anyRequest().
                    authenticated();    //其他地址需要认证授权
        }
    }
    

         用户每次访问微服务的时候,需要先申请令牌,令牌申请后,每次将令牌放到 Http headers 中,才能访问微服务。Http headers 中每次 需要 添加一个 Authorization 头信息,头的值为 bearer token("bearer"空格 [token])
        比如,先不携带令牌测试,访问 http://localhost:18087 /user ,不携带令牌,结果如下(因为这时网关获取不到令牌,所以响应 401 错误状态码):
    在这里插入图片描述
        携带正确令牌访问(这时网关可以获取到令牌信息,予以放行):
    在这里插入图片描述
        而且对于 configure 方法中设置的对 user/add 路径放行,可以看到,不需要在 headers 中传 Authorization 参数,确实放行了:
    在这里插入图片描述


    (2)网关微服务
         接下来,需要让 OAuthorization 对接网关微服务。用户每次访问微服务的时候,先去 OAuth2.0 服务登录,登录后再访问微服务网关,微服务网关将请求转发给其他微服务处理。
    **1562729873478**
        在上一篇博客,搭建了 changgou-user-oauth 微服务,实现了 9001/user/login 的登录功能,在上上一篇博客中,搭建了 changgou-gateway-web 微服务,提供了 AuthorizeFilter 全局过滤器,总的来说,实现了以下功能:
    (1)用户登录成功(也就是用户名和密码正确)后,会将令牌信息存入到 cookie 中
    (2)用户携带 Cookie 中的令牌 访问微服务网关
    (3)微服务网关先获取头文件中的令牌信息,如果 HTTP Headers 中没有 Authorization 令牌信息,则到参数中找,参数中如果没有,则到 Cookie 中找,最后将令牌信息封装到 HTTP Headers ,并调用其他微服务
    (4)其他微服务会获取 HTTP Headers 中的 Authorization 令牌信息,然后匹配令牌数据是否能使用公钥解密,如果解密成功说明用户已登录,解密失败,说明用户未登录

        修改 changgou-gateway-web 的全局过滤器 AuthorizeFilter 类的逻辑,如果令牌不在 Http Headers 头文件中,需要将 bearer 令牌信息添加到头文件中,而且,现在的令牌是经过私钥生成的,所以是需要用公钥验证,之前的解析JWT的代码不能用啦,先注释掉:
    在这里插入图片描述
    这时访问 http://localhost:8001/api/user ,将通过私钥生成的新令牌放到头文件中,在令牌前面添加 Bearer 令牌:
    在这里插入图片描述
        这里 全局过滤器 AuthorizeFilter的逻辑是,从 Http Headers 中获取到了 Authorization 参数,所以就执行了 chain.filter(exchange) 放行,后续是需要把解析令牌的方法重新提供的。
        而且在 AuthorizeFilter 类中,是依次从头文件、参数、Cookie 中获取 Authorization 参数的,所以一次传过 Authorization 参数,没有清空 Cookie 且未过期的话,后续就不需要传了;或者通过传参数的形式,是不需要加 "bearer " 前缀的,因为代码逻辑里会把 token 取出,再加上"bearer " 前缀放到 Http Headers 中:
    在这里插入图片描述