如何使用刷新令牌在Oauth 2.0中重新生成访问令牌

问题描述 投票:2回答:1

我们使用Spring Cloud Netflix Zull作为后端服务的网关应用程序。前端是Angular。但我们只测试Postman中的端点(前端正在开发中)。我们有一个名为LoginServiceModule的模块,另一个是ZullServerModuleLoginSericeModuke从前端获取用户名和密码,并通过包含所需的标题和正文来调用以下oauth / token端点。

 http://localhost:XXXX/login

并且回应是

{
    "access_token": "XXXXXXXXX",
    "token_type": "bearer",
    "refresh_token": "XXXXXXXXX",
    "expires_in": 3600,
    "scope": "read write",
    "jti": "XXXXXXXXXXX"
}

ZullServerModule包含ZullServerConfiguration,授权服务器配置和资源服务器配置等...

qazxsw poi内部调用了oauth / token端点。

LoginModule

而且回应是......

ResponseEntity<String> loginResponse =  restTemplate.exchange("http://localhost:XXXX/oauth/token", HttpMethod.POST, entity, String.class);

我们从响应中提取access_token并调用以下端点...

{
    "access_token": "XXXXXXXXX",
    "token_type": "bearer",
    "refresh_token": "XXXXXXXXX",
    "expires_in": 3600,
    "scope": "read write",
    "jti": "XXXXXXXXXXX"
}

但是当access_token到期时,以及当我访问上面的后端服务url时,它的说法

http://localhost:XXXX/ProjectName/api/endpointname?access_token={access_token}.

我知道它已经过期,并尝试在终端的refresh_token帮助下重新生成access_token,就像这样

curl clientID:clientSecret @ localhost:XXXX / oauth / token -d grant_type = refresh_token -drefresh_token = {refresh_token}

但我需要在我们的代码中包含它,并且不知道将它放在何处。在网上搜索后,我偶然发现了{ "error": "invalid_token", "error_description": "Access token expired:XXXXXXXXXXXXXXX(access_token)" } 。我尝试了所有pre,route和post过滤器。对于每个请求,它们都被执行(即只要access_token未过期),但是当令牌过期并且如果我测试端点时,没有任何过滤器被执行并且我得到错误响应

ZullFilter

我已经在每个过滤器的run方法中放置了sysouts。我对filterOrder也不太了解。

{
    "error": "invalid_token",
    "error_description": "Access token expired: XXXXXXXXXX"
}

我想借助refresh_token控制access_token生成。我怎么能在access_token到期时编码,如果我在到期后访问资源,那么我知道该令牌已过期并重新生成access_token并使用新的access_token调用前一个调用。

java spring-boot oauth-2.0 spring-cloud-netflix
1个回答
2
投票

通常,客户端负责维护自己的令牌,并在即将到期时刷新令牌。将此逻辑移动到您的Zuul层似乎是一个非常糟糕的主意。考虑一下实施,它将如何工作?

一旦客户端的令牌过期,它将使用永久过期的令牌调用您的终端,Zuul必须尝试使用​​每个请求刷新。这会为每个API调用增加很多开销。你可能会引入某种黑客,你总是在响应头或其他东西中传回一个新的令牌......但此时你会违反@Override public Object run() throws ZuulException { System.out.println("pre filter..."); RequestContext context = RequestContext.getCurrentContext(); HttpServletResponse response = context.getResponse(); System.out.println(response.getStatus()); return null; }

© www.soinside.com 2019 - 2024. All rights reserved.