网关上认证去做哪些改造
在网关上用jwt去解析用户信息,而不再发送校验令牌的请求了。
之前的时候网关上实际上写了很多的代码
包括认证,发check_token去把token请求,换成用户信息。
这俩是审计日志和授权。
自己写了个MeFilter获取用户的信息
限流
filter都删掉,Spring Security和Spring OAuth 已经把所有的都封装好了。除了限流和日志。审计、认证、授权都封装好了。
用Spring Security实现功能
加入Starter-oauth2的依赖。
本节课先讲认证相关的功能。我们现在不再发校验令牌的请求,而是直接从jwt里面读取用户的信息,jwt的信息会有一个签名,读取信息的时候要去验这个签名,验签名的时候需要有一个key,key我们需要在Gateway启动的时候,从认证服务器获取到这个key
key-uri首先要配置从哪里拿key。这里应该配置的是认证服务器的地址。
tokenKey源码在这里
TokenKeyEndpoint来处理,/oauth/token_key这个请求。
它就会把证书里面存的密钥返回
上节课配置tokenStore的时候
下面配置配置了tokenKeyAccess。就是说访问这个tokenKeyUrl的时候必须要身份认证。
所以在这里我就要告诉他身份认证的信息。clinetId和clientSceret
网关就是gateway密码是123456
这和我们数据库的记录是对应的。数据库内有这条记录才会生效。
配置资源服务器相关的配置
网关是作为资源服务器存在的,所以继承ResourceServerConfigAdapter
我们自己写的认证的时候,我们要把所有/token的请求都放过去,因为/token开头的请求都是在申请令牌,你不能让申请令牌的这些请求也需要身份认证。
默认情况下所有的请求都需要身份认证。
我们在这里 加一句,申请令牌的所有请求都放行。不需要带令牌。
如果你还有其他的路径需要放行的直接在这里逗号分隔开 继续加字符串就可以了。这里的antMathers是个复数的形式。
order-api
我们在网关里面把filter都去掉了。已经不再传明文的username了。这个时候order-api也需要修改代码
因为oauth2的依赖。
也需要响应的配置,令牌传递过来,它也需要从令牌里解析当前用户是谁。因为我们传的是一个令牌,而不是明文的一个东西了。
在启动类里面加注解@EnableResourceServer
拿到用户名,通过@AuthenticationPrincipal注解
启动测试
启动网关
在没有启动认证服务器的时候,直接启动网关 会报错。链接被拒绝,
它在启动的时候会去找认证服务器,拿签名的key。认证服务器如果还没有启动,连不上,所以会报错。你拿不到这个key 就没法验jwt
所以首先启动认证服务器,OAuth2的认证服务器。
然后再启动网关、
再次启动网关的时候又报了个404的错误。就是刚才那个拿key的路径没有。
这是因为我们在配置Oauth2认证服务器的时候,改tokenStore的时候,声明的是私有的JwtAccessTokenConverter
这个类要声明称公有的,而且还要是Spring的一个Bean。只有在有这个Bean的情况下。
tokenKeyEndpoint这个端点才会起作用。
这个请求才会被处理
如果没有这个public的Bean。这个端点是不会暴露的,所以就会报404 的错误。
重启认证服务器
网关重启
网关就能成功的启动了。
启动orderapi
首先来获取令牌
我把数据库内的令牌的过期时间改了 之前为了测试改的10秒。这次再改的长一点。
通过网关调用创建订单的服务
403错误。无效的token,不包含resource id oauth2-resouce 这说明我们的resouceid的检查没过。
针对admin发出去的令牌,它的resource_id是order-server
报错的oauth2-server是哪里的呢???我们在配置网关的时候,没有指定resource_id
默认情况下没有指定resourceId的情况,这个类里面会有一个默认的resourceId.进入到ResourceServerSerurityConfigurer
因为网关没有配置,所以默认的就是这个类里的resourceId,oauth2-resource
我们在发出去的令牌只能访问order-server
所以这个令牌在访问网关的时候,就被拦下来了。令牌是对的。但是没有权限。
令牌随便加个字母访问,错误的令牌就是401
令牌都没过,无法从令牌里面知道你是谁。invalid_token无效的令牌。
我们之前在网关上做的认证和权限判断,就是返回401和403两个事,实际上,spring security已经帮我们都做了。
我们看到了它上面基友401认证的判断,也有403权限的判断。
解决方法
在数据库内,这里加一个gateway
然后把网关的resourceId配置成gateway
再重新发一个令牌,这个令牌再去访问网关,就可以过去了。
这种方式的好处就是你可以控制权限。这个令牌能访问谁,不能访问谁,自己可以控制。不好的地方就是麻烦,每次都要自己改数据,代码里还要做相应的编码。
比如说这里的名字你编译下,数据库内的数据也要跟着改。这样还是需要一些维护的工作的。
另外一种方式
数据库内 这里啥都不填,这样发出去的令牌就可以访问所有的resourceId
配置gateway的resourceId也去掉。
这里我们就是通过数据库配置为空的方式了。
重新测试
重新申请令牌。
新凌派就是可以访问任何的资源服务器。
访问创建订单的服务。
创建订单的控制台,把用户名打印出来。
发了jwt后,在网关的时候,没有去校验令牌,在网关解析了jwt,判断这个jwt是有效的,再往下,jwt给到订单服务的时候,订单服务从jwt解析出来这个令牌对应的用户是jojo
解决最后一个问题,令牌如何传递
订单服务想去调库存服务的时候,令牌如何往下传。仍然要从请求里面拿到令牌,放到请求头里。但是spring security已经帮我封装了。不用自己去做。只需要用他的一个工具类就可以了。
价格服务
价格服务也加上oauth2的依赖
加上配置,配置从哪里拿tokenKey
数据库内没有priceService
把orderApp改成priceService ,密码是复制上面gateway的密码。
获取用户名
输出用户名
修改orderController
在请求上把令牌带上。不再用原来的restTemplate了 ,而是用SpringSecurity提供的OauthRestTemplate
OauthRestTemplate功能就是从你当前请求的上下文里,拿到令牌,然后把令牌放到请求头里面。然后再出去。只要用OauthRestTemplate来发请求就会自动带上请求头。
在springboot的启动类声明oauth2RestTemplate
这个方法。
需要用到两个参数。
进入到OAuth2RestTemplate这个类里面。
复制这两个参数出来。
复制到方法的参数里就可以了。这两个参数springboot已经帮我们声明好了。直接写在方法参数里,springboot就会替我们把这俩参数传进来。
然后直接传给这个OAuth2ResetTemplate就可以了。
启动测试
orderAPi和priceAPI都启动起来。
听过网关来调创建订单。
priceAPi的控制台