Coder Social home page Coder Social logo

Comments (24)

kakawait avatar kakawait commented on May 28, 2024 3

@skyding1212 As I said

you should use bean LoadBalancerInterceptor interceptor if you don't add spring-retry

So you need to autowired LoadBalancerInterceptor instead

@Bean
UserInfoRestTemplateCustomizer userInfoRestTemplateCustomizer(LoadBalancerInterceptor loadBalancerInterceptor) {
    return template -> {
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(loadBalancerInterceptor);
        AccessTokenProviderChain accessTokenProviderChain = Stream
                .of(new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
                        new ResourceOwnerPasswordAccessTokenProvider(), new ClientCredentialsAccessTokenProvider())
                .peek(tp -> tp.setInterceptors(interceptors))
                .collect(Collectors.collectingAndThen(Collectors.toList(), AccessTokenProviderChain::new));
        template.setAccessTokenProvider(accessTokenProviderChain);
    };
}

Or add dependencies as @alexandr-efimov explained above

Sample was updated to Spring boot 1.5.7 and Spring Cloud Dalston SR3 https://github.com/kakawait/uaa-behind-zuul-sample

from spring-cloud-security.

martijnhiemstra avatar martijnhiemstra commented on May 28, 2024 3

I have tried all the solutions mentioned above and NONE!!! of them work. This is a major flaw in Spring since now a days with discovery services almost becoming standard it should be working. Does anybody know what the status of this is?

from spring-cloud-security.

skyding1212 avatar skyding1212 commented on May 28, 2024 2

@kakawait
could you provide a support for Dalston version? I try it but can not find uaa-service...

from spring-cloud-security.

alexandr-efimov avatar alexandr-efimov commented on May 28, 2024 1

@skyding1212 I had the same problem with Dalston. But sulution providen by @kakawait work fine(that was for CAMDEN version) with dependency solved all problems!

<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
            <version>1.2.0.RELEASE</version>
</dependency>

from spring-cloud-security.

spencergibb avatar spencergibb commented on May 28, 2024 1

No there hasn't. If there is, we will update the issue.

from spring-cloud-security.

dsyer avatar dsyer commented on May 28, 2024

I agree that might be cool, when the auth server is a registered service. Contributions gladly accepted. Note (for anyone attempting a pull request): the userAuthorizationUri is passed back to the browser in a redirect, so we would need to inject a custom RedirectResolver. The accessTokenUri is used in a back channel inside the OAuth2RestTemplate, so it will also be fiddly (but not impossible) to override the nested RestTemplate used for that call.

from spring-cloud-security.

huningd avatar huningd commented on May 28, 2024

We have the same situation for property security.oauth2.resource.userInfoUri. In this case wouldn't it be enough to inject the DiscoveryClient into org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices? If a DiscoveryClient is available we use it to resolve the userinfo service uri. Something like this:

public UserInfoTokenServices(String userInfoEndpointUrl, String clientId, DiscoveryClient discoveryClient){
    String uri = discoveryClient.getInstances(userInfoEndpointUrl).get(0).getUri().toString();
    this.userInfoEndpointUrl = uri;
    this.clientId = clientId;
}

If that is enough I would enhance the UserInfoTokenServices and configuration classes.

from spring-cloud-security.

dsyer avatar dsyer commented on May 28, 2024

That won't work in quite that form because UserInfoTokenServices is part of Spring Boot now (which knows nothing about discovery).

from spring-cloud-security.

huningd avatar huningd commented on May 28, 2024

Didn't saw that UserInfoTokenServices is from spring-boot-autoconfigure. Never develop in a text editor, sorry. So you mean you would enhance spring-cloud-security. Does that mean you would provide alternative configurations, exclude original configurations from spring-boot-autoconfigure and provide some alternative implementations. Do you have some recommendation how we could start to solve this?

from spring-cloud-security.

huningd avatar huningd commented on May 28, 2024

We solved it now with the UserInfoRestTemplateCustomizer. It workes great for us:

    @Override
    public void customize(OAuth2RestTemplate template) {
        template.setRequestFactory(ribbonClientHttpRequestFactory);
    }

from spring-cloud-security.

kakawait avatar kakawait commented on May 28, 2024

@huningd good catch. However that is not enough to also support security.oauth2.client.accessTokenUri

You can do that thing (ATTENTION not heavily tested and only tested with authorization-code mode, copy at your own risk)

CAMDEN VERSION (you should use bean LoadBalancerInterceptor interceptor if you don't add spring-retry)

@Bean
UserInfoRestTemplateCustomizer oauth2RestTemplateCustomizer(RetryLoadBalancerInterceptor interceptor) {
    List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
    interceptors.add(interceptor);
    return template -> {
        AccessTokenProviderChain accessTokenProviderChain = Stream
                .of(new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
                        new ResourceOwnerPasswordAccessTokenProvider(), new ClientCredentialsAccessTokenProvider())
                .peek(tp -> tp.setInterceptors(interceptors))
                .collect(Collectors.collectingAndThen(Collectors.toList(), AccessTokenProviderChain::new));
        template.setAccessTokenProvider(accessTokenProviderChain);
    };
}

BRIXTON VERSION

@Bean
UserInfoRestTemplateCustomizer userInfoRestTemplateCustomizer(SpringClientFactory springClientFactory) {
    return template -> {
        AccessTokenProviderChain accessTokenProviderChain = Stream
                .of(new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
                        new ResourceOwnerPasswordAccessTokenProvider(), new ClientCredentialsAccessTokenProvider())
                .peek(tp -> tp.setRequestFactory(new RibbonClientHttpRequestFactory(springClientFactory)))
                .collect(Collectors.collectingAndThen(Collectors.toList(), AccessTokenProviderChain::new));
        template.setAccessTokenProvider(accessTokenProviderChain);
    };
}

With that Bean following configuration is working

security:
  oauth2:
    client:
      accessTokenUri: http://uaa-service/oauth/token

where uaa-service is service name (is not a resolvable hostname)

It can be a partial response for #94 we just need a trick for userAuthorizationUri (currently possible as explained on POC) because userAuthorizationUri is used by browser (during redirection) so we can't (and we must not) use service registry

from spring-cloud-security.

kakawait avatar kakawait commented on May 28, 2024

@skyding1212 sorry but I've just upgraded my project to Dalston and Spring boot 1.5.2 and I don't face any issue with that code when using Camden version

from spring-cloud-security.

HJK181 avatar HJK181 commented on May 28, 2024

Any progress on that?

from spring-cloud-security.

Pryanic avatar Pryanic commented on May 28, 2024

Any progress on that?

from spring-cloud-security.

nickorfas avatar nickorfas commented on May 28, 2024

@dsyer on your first response of this issue you said that "The accessTokenUri is used in a back channel inside the OAuth2RestTemplate, so it will also be fiddly (but not impossible) to override the nested RestTemplate used for that call." This is exactly what is happening even in Spring Cloud Edward.SR2... Is there any way that you can think on how eureka instanceId could be used for access-token-uri?

from spring-cloud-security.

stereo720712 avatar stereo720712 commented on May 28, 2024

it will errror when jwt token is expired and need to refresh .
Why ?

from spring-cloud-security.

stereo720712 avatar stereo720712 commented on May 28, 2024

it should be ribbon issue, because it only refresh token fail with the load balance inteceptor
and call it fail because of not change the service name to ip .

from spring-cloud-security.

ZoomAll avatar ZoomAll commented on May 28, 2024

I have encountered a similar problem with authentication server name resolution. I will describe how I solved it.

application.properties

security.oauth2.client.client-id=trusted
security.oauth2.client.client-secret=trusted
security.oauth2.resource.token-info-uri=http://NEVIS/oauth/check_token
        
ribbon.http.client.enabled=true

Pay attention to ribbon.http.client.enabled=true - without it will not be created RibbonClientHttpRequestFactory bean.

Configure RestTemplate to use the Ribbon functionality:

@Configuration
public class BaliRestClientConfig
{
  /**
   * Customize the RestTemplate to use Ribbon load balancer to resolve service endpoints
   */
  @Bean
  public RestTemplateCustomizer ribbonClientRestTemplateCustomizer(
          final RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory)
  {
    return restTemplate -> restTemplate.setRequestFactory(ribbonClientHttpRequestFactory);
  }
}

this configurator will work for all RestTemplate instances: RestTemplate, OAuth2RestTemplate, etc.

Now we need to force RemoteTokenServices to use our RestTemplate instance.
Because in my case the main problem was that RemoteTokenServices itself creates its own personal RestTemplate.
Reassign the RestTemplate instance to RemoteTokenServices at the time It is defined:

  @Autowired
  private RemoteTokenServices remoteTokenServices;

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate()
  {
    var restTemplate = new RestTemplate();
    remoteTokenServices.setRestTemplate(restTemplate);
    return restTemplate;
  }

And that's all.

The short sequence will be as follows:

  1. RemoteTokenServices instance automatically created and configured, next
  2. Create RestTemplate bean and assign it to remoteTokenServices.setRestTemplate(restTemplate);, next
  3. Custom RestTemplate to use the Ribbon functionality restTemplate.setRequestFactory(ribbonClientHttpRequestFactory);

When a POST request is sent to http://NEVIS/oauth/check_token, RemoteTokenServices can now resolve the name of the NEVIS authentication server because it is associated with the RestTemplate that is associated with the Ribbon :)

from spring-cloud-security.

andye2004 avatar andye2004 commented on May 28, 2024

@dsyer I've just been looking at how to resolve this issue for myself and been thinking about your very first comment re the browser userAuthorizationUri redirect. Whilst the feature itself is a cool idea I was thinking that from a Spring Security OAuth2 perspective we really shouldn't be pulling in any discovery client. Instead, it should probably be a default implementation doing pretty much what is done now but also providing an over-ride mechanism where people can provide their own RedirectResolver to account for whatever discovery service they are using?

There have already been a few posts above that highlight how to take care of the other redirect issues so if you agree with this kind of approach I've suggested I can have a look at putting a PR together that would cover it.

from spring-cloud-security.

tuhao1020 avatar tuhao1020 commented on May 28, 2024

Anybody knows when would the PR #1523 be merged?

from spring-cloud-security.

ryanjbaxter avatar ryanjbaxter commented on May 28, 2024

That is not a valid PR# can you provide a link?

from spring-cloud-security.

tuhao1020 avatar tuhao1020 commented on May 28, 2024

@ryanjbaxter spring-attic/spring-security-oauth#1523

from spring-cloud-security.

ryanjbaxter avatar ryanjbaxter commented on May 28, 2024

Why don’t you comment on that PR and ask?

from spring-cloud-security.

davicarrano avatar davicarrano commented on May 28, 2024

I have encountered a similar problem with authentication server name resolution. I will describe how I solved it.

application.properties

security.oauth2.client.client-id=trusted
security.oauth2.client.client-secret=trusted
security.oauth2.resource.token-info-uri=http://NEVIS/oauth/check_token
        
ribbon.http.client.enabled=true

Pay attention to ribbon.http.client.enabled=true - without it will not be created RibbonClientHttpRequestFactory bean.

Configure RestTemplate to use the Ribbon functionality:

@Configuration
public class BaliRestClientConfig
{
  /**
   * Customize the RestTemplate to use Ribbon load balancer to resolve service endpoints
   */
  @Bean
  public RestTemplateCustomizer ribbonClientRestTemplateCustomizer(
          final RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory)
  {
    return restTemplate -> restTemplate.setRequestFactory(ribbonClientHttpRequestFactory);
  }
}

this configurator will work for all RestTemplate instances: RestTemplate, OAuth2RestTemplate, etc.

Now we need to force RemoteTokenServices to use our RestTemplate instance.
Because in my case the main problem was that RemoteTokenServices itself creates its own personal RestTemplate.
Reassign the RestTemplate instance to RemoteTokenServices at the time It is defined:

  @Autowired
  private RemoteTokenServices remoteTokenServices;

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate()
  {
    var restTemplate = new RestTemplate();
    remoteTokenServices.setRestTemplate(restTemplate);
    return restTemplate;
  }

And that's all.

The short sequence will be as follows:

  1. RemoteTokenServices instance automatically created and configured, next
  2. Create RestTemplate bean and assign it to remoteTokenServices.setRestTemplate(restTemplate);, next
  3. Custom RestTemplate to use the Ribbon functionality restTemplate.setRequestFactory(ribbonClientHttpRequestFactory);

When a POST request is sent to http://NEVIS/oauth/check_token, RemoteTokenServices can now resolve the name of the NEVIS authentication server because it is associated with the RestTemplate that is associated with the Ribbon :)

It works to me. Thaks.

from spring-cloud-security.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.