听起来可能有些奇怪。但是我有一种情况,我的应用程序需要使用属性从用户属性中获取ROPC令牌请求。
当有一个随机的匿名传入请求时,将触发该呼叫。但是在令牌请求中,令牌请求到达AccessTokenProviderChain.class
时失败。
org.springframework.security.authentication.InsufficientAuthenticationException:必须进行身份验证才能获取访问令牌(不允许匿名)
在调试时,我发现它发生在下面的行中。
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof AnonymousAuthenticationToken && !resource.isClientOnly()) {
throw new InsufficientAuthenticationException("Authentication is required to obtain an access token (anonymous not allowed)");
}
我看到AnonymousAuthenticationFilter
将主体设置为anonymousUser
@EnableMongoAuditing
。除了创建自定义令牌请求之外,还有其他方法可以解决此问题。
代码:
public OAuth2RestTemplate myappROPCRestTemplate() {
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(myappPasswordResourceDetails());
restTemplate.setAccessTokenProvider(getAccessTokenProvider());
if (proxyEnabled) {
restTemplate.setRequestFactory(getRequestFactoryWithProxy());
}
return restTemplate;
}
private AccessTokenProvider getAccessTokenProvider() {
ResourceOwnerPasswordAccessTokenProvider resourceOwnerPasswordAccessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
if (proxyEnabled) {
resourceOwnerPasswordAccessTokenProvider.setRequestFactory(getRequestFactoryWithProxy());
}
return new AccessTokenProviderChain(Collections.singletonList(resourceOwnerPasswordAccessTokenProvider));
}
private SimpleClientHttpRequestFactory getRequestFactoryWithProxy() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setOutputStreaming(false);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
requestFactory.setProxy(proxy);
return requestFactory;
}
private OAuth2ProtectedResourceDetails myappPasswordResourceDetails() {
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setAccessTokenUri(tokenUrl);
resource.setClientId(clientId);
resource.setClientSecret(clientSecret);
resource.setUsername(username);
resource.setPassword(password);
resource.setClientAuthenticationScheme(AuthenticationScheme.form);
resource.setGrantType("password");
return resource;
}