现在任何连接都要经过网关,所以在网关校验access_token的正确性,当access_token正确后,才转发到相应的服务。
当获取access_token后,每次前端访问都要带上这个access_token。
依次启动服务,eureka---->user------>oauth---------->zull顺序启动服务
现在我们访问127.0.0.1:9999/user/hello 这个接口
到现在为止无论带不带access_token都可以访问这个接口,并返回结果。显然这不是我想要的。
所以接下来要改造,只有携带了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,这里配置只要认证通过后才能访问接口
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了
上面就是我们在oauth中设置的秘钥,我们要在网关拿到它,其实很简单,只需要把配置文件配好就ok了
在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还能用的问题)
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去访问
现在已经不能访问
当我们在herder中带上access_token
注意注意:access_token最前面一定要加bearer前缀
我这个token已经过期了,所以报错了,我重新获取一个新的token
带上这个token访问
已经访问到了。
不带上就会报错,我把Authorization 前面的钩去掉访问,访问不到
说明此时已经控制到了,除了转发到oauth服务不需要token,其余都要带上token才能访问。