InsufficientAuthenticationException:在进行ROPC令牌请求时,需要进行身份验证才能获得访问令牌(不允许匿名)

时间:2019-04-01 09:54:12

标签: java spring-security oauth-2.0 spring-security-oauth2 spring-oauth2

听起来可能有些奇怪。但是我有一种情况,我的应用程序需要使用属性从用户属性中获取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

  • 这是因为传入请求是匿名的,并且我正在尝试发出ROPC令牌请求吗?
  • 是因为启用了@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;
}

0 个答案:

没有答案