如何在spring-security-oauth 2.2.1.RELEASE

时间:2018-02-21 13:31:03

标签: oauth-2.0 access-token spring-security-oauth2 refresh-token

我正在实施一个客户端,使用OAuth2对WSO2进行身份验证,我在刷新访问令牌时遇到了严重问题,获得了401 UNAUTHORIZED。虽然我已经发现了Spring OAuth2代码的作用,但我不知道为什么它的行为在2.2.1.RELEASE中发生了变化,对我来说这似乎是完全错误的。实际上使用2.0.14.RELEASE可以工作。

在我向你展示之前,我已经做了什么以及我已经发现了什么之前,让我提出我的问题:

我应该如何使用客户端凭据而不是用户凭据来实现自动令牌刷新的OAuth2客户端?

所以这就是我到目前为止实施的内容。由于没有用户会话,客户端使用OAuth2RestTemplate ResourceOwnerPasswordResourceDetails标记isClientOnly配置true @Bean protected OAuth2ProtectedResourceDetails resource() { ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails() { @Override public boolean isClientOnly() { return true; } }; List<String> scopes = new ArrayList<>(2); scopes.add("write"); scopes.add("read"); resource.setScope(scopes); resource.setGrantType("password"); resource.setAccessTokenUri(TOKEN_URL); resource.setClientId(MY_CLIENT_ID); resource.setClientSecret(MY_CLIENT_SECRET); resource.setUsername(MY_SERVICE_USER); resource.setPassword(MY_SERVICE_USER_PW); return resource; } @Bean public OAuth2RestOperations restTemplate() { AccessTokenRequest atr = new DefaultAccessTokenRequest(); OAuth2RestTemplate template = new OAuth2RestTemplateWithBasicAuth(resource(), new DefaultOAuth2ClientContext(atr)); List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(); interceptors.add(new LoggingRequestInterceptor()); template.setInterceptors(interceptors); template.setRetryBadAccessTokens(true); return template; } 。可以成功建立客户端会话,并设置访问令牌和刷新令牌。

AccessTokenProviderChain#obtainAccessToken

到目前为止一切顺利。我已经证实这基本上有效。

但是一旦访问令牌过期,我经常遇到401错误,因为没有执行令牌刷新。相反,执行普通的身份验证请求,但使用客户端密钥和密码而不是用户/密码。简而言之,我已经通过spring-security-oauth2调试我的方式进入 if (resource.isClientOnly() || (auth != null && auth.isAuthenticated())) { // P1 existingToken = request.getExistingToken(); if (existingToken == null && clientTokenServices != null) { existingToken = clientTokenServices.getAccessToken(resource, auth); } if (existingToken != null) { if (existingToken.isExpired()) { if (clientTokenServices != null) { clientTokenServices.removeAccessToken(resource, auth); } OAuth2RefreshToken refreshToken = existingToken.getRefreshToken(); if (refreshToken != null && !resource.isClientOnly()) { // P2 accessToken = refreshAccessToken(resource, refreshToken, request); } } else { accessToken = existingToken; } } } 并发现,是否执行了令牌刷新请求是在下面的代码中决定的。 See on Github

auth

正如您在P1处所见,如果存在授权用户会话(clientOnly)或资源配置为isClientOnly() == true && auth == null,则会输入阻止。由于我没有用户,但我处于链接服务方案中,我有!isClientOnly()。但是在P2,实际进行刷新的最终决定是通过要求 try { JSONArray jsonarray = new JSONArray(response); for (int i = 0; i < jsonarray.length(); i++) { JSONObject jsonobject = jsonarray.getJSONObject(i); String name = jsonobject.getString("Sno"); String Tktid = jsonobject.getString("TKTID"); link = jsonobject.getString("Link"); List list = new List(jsonobject.getString("Sno"), jsonobject.getString("TKTID"),jsonobject.getString("Link")); tktList.add(list); Log.i("website content", name); Log.i("website content", Tktid); Log.i("website content", link); } //creating custom adapter object ListViewAdapter adapter = new ListViewAdapter(tktList, getApplicationContext()); //adding the adapter to listview listView.setAdapter(adapter); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //displaying the error in toast if occurrs Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show(); } }); 来规定的。因此,这仅在客户端方案中有效地禁止刷新请求。

这是2.2.1版本之前的版本,我发现,这似乎是对以下Issue的修复。对我来说,这似乎是完全错误的。

此外,对我来说,补丁似乎打破了客户端功能,以修复实际的服务器错误行为。正如您在问题讨论中看到的那样,我已经对此进行了评论。但是当这个问题被关闭并且spring-security-oauth2论坛指出应该在StackOverflow上进行讨论时,我在这里寻求帮助。

同样问题:如何将客户端应用程序配置为通过OAuth2RestTemplate使用OAuth2安全服务,以及一小时的访问令牌运行时和刷新令牌运行时(比方说两小时)。

0 个答案:

没有答案
相关问题