现在任何连接都要经过网关,所以在网关校验access_token的正确性,当access_token正确后,才转发到相应的服务。

当获取access_token后,每次前端访问都要带上这个access_token。

依次启动服务,eureka---->user------>oauth---------->zull顺序启动服务

现在我们访问127.0.0.1:9999/user/hello 这个接口

spring cloud 2023 用户授权 spring cloud权限验证_spring

到现在为止无论带不带access_token都可以访问这个接口,并返回结果。显然这不是我想要的。

spring cloud 2023 用户授权 spring cloud权限验证_spring_02

所以接下来要改造,只有携带了access_token,并且正确后才能访问这个接口。

在网关zuul加入oauth2的包

<!--oauth-->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        </dependency>

然后添加配置类ResourceServerConfiguration.java,这里配置只要认证通过后才能访问接口

spring cloud 2023 用户授权 spring cloud权限验证_spring_03

package com.study.vcloud.zuul.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

/**
 * @author Pan Weilong
 * @date 2019/8/15 22:45
 * @description: 接口.
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {


    @Override
    public void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
                .authorizeRequests();
        //经过oauth服务的连接全部放行,不然token会获取不到
        registry.antMatchers("/oauth/**").permitAll();
        //任何连接只要认证后放行
        registry.anyRequest().authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
         //跟oauth中的值必须一样
        resources.resourceId("vcloud");
    }


}

上面配置了只要认证通过后放行。但是怎么知道access_token的合法性呢??

有两种方法

方法一:从auth服务中获取秘钥,然后在zuul网关拿到加密秘钥验证token的合法性(这种有弊端:就是退出登录后以前的token还可以继续访问接口)

首先我们要知道jwt加密的过程,我这里就不说了,百度上有可以搜一下。

我这里主要是获取oauth中的设置的秘钥,然后网关会自动去验证这个token,我们只需要把oauth中秘钥在网关获取到就ok了

spring cloud 2023 用户授权 spring cloud权限验证_spring_04

上面就是我们在oauth中设置的秘钥,我们要在网关拿到它,其实很简单,只需要把配置文件配好就ok了

spring cloud 2023 用户授权 spring cloud权限验证_Server_05

在zuul网关的application.yml加上上面的配置就好了

security:
  auth:
    server: http://127.0.0.1:1027 #认证服务地址
  oauth2:
    client:
      client-id: client_id   #oauth中的client_id值
      client-secret: client_secret #oauth中的client-secret值
    resource:
      loadBalanced: true
      jwt:
        key-uri: ${security.auth.server}/oauth/token_key #解析jwt令牌所需要密钥的地址

上面信息写的很详细了,上面的获取秘钥是在zuul服务启动的时候就会去获取秘钥,而不是每次获取。

配置好后,网关会去自动校验token合法性以及是否过期。

 

第二种:在网关拿到token后去oauth服务中检验token的正确性(这种方式就不会产生退出登录后以前的token还能用的问题)

spring cloud 2023 用户授权 spring cloud权限验证_spring_06

security:
  auth:
    server: http://127.0.0.1:1027
  oauth2:
    client:
      client-id: client_id
      client-secret: client_secret
    resource:
      loadBalanced: true
      token-info-uri: ${security.auth.server}/oauth/check_token #auth服务中验证token
      #jwt:
        #key-uri: ${security.auth.server}/oauth/token_key #解析jwt令牌所需要密钥的地址

添加了

security.oauth2.resource.token-info-uri: ${security.auth.server}/oauth/check_token #验证auth服务中验证token

每次调用接口都会去oauth服务中校验token的正确性。

一般到这里就配置完成了。

可以拿一个错误的token去访问接口,如果以第二种方式程序报错的话(报什么转换异常的问题以及400 null),

可以看这篇文章。《zuul网关调用oauth/check_token成功,解析失败》

启动项目测试:

我们现在来访问最开始的那个接口127.0.0.1:9999/user/hello

当我们不带access_token去访问

spring cloud 2023 用户授权 spring cloud权限验证_Express_07

现在已经不能访问

 

当我们在herder中带上access_token

spring cloud 2023 用户授权 spring cloud权限验证_Server_08

注意注意:access_token最前面一定要加bearer前缀

我这个token已经过期了,所以报错了,我重新获取一个新的token

spring cloud 2023 用户授权 spring cloud权限验证_Express_09

带上这个token访问

spring cloud 2023 用户授权 spring cloud权限验证_Server_10

已经访问到了。

不带上就会报错,我把Authorization 前面的钩去掉访问,访问不到

spring cloud 2023 用户授权 spring cloud权限验证_Express_11

说明此时已经控制到了,除了转发到oauth服务不需要token,其余都要带上token才能访问。