Spring 4.0.0 basic authentication with RestTemplate

前端 未结 6 1726
梦谈多话
梦谈多话 2020-12-13 10:37

I am currently working on integration of a third party application with our local reporting system. I would like to implement REST calls with basic authentication but facing

6条回答
  •  爱一瞬间的悲伤
    2020-12-13 11:17

    From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/ with HttpClient 4.3 edits:

    Both Spring 3.0 and 3.1 and now 4.x have very good support for the Apache HTTP libraries:

    1. Spring 3.0, the CommonsClientHttpRequestFactory integrated with the now end of lifed HttpClient 3.x
    2. Spring 3.1 introduced support for the current HttpClient 4.x via HttpComponentsClientHttpRequestFactory (support added in the JIRA SPR-6180)
    3. Spring 4.0 introduced async support via the HttpComponentsAsyncClientHttpRequestFactory

    Let’s start setting things up with HttpClient 4 and Spring 4.

    The RestTemplate will require an HTTP request factory – a factory that supports Basic Authentication – so far, so good. However, using the existing HttpComponentsClientHttpRequestFactory directly will prove to be difficult, as the architecture of RestTemplate was designed without good support for HttpContext – an instrumental piece of the puzzle. And so we’ll need to subclass HttpComponentsClientHttpRequestFactory and override the createHttpContext method: (taken from soluvas-framework on GitHub)

    package org.soluvas.commons.util;
    
    import java.net.URI;
    
    import javax.annotation.Nullable;
    
    import org.apache.http.HttpHost;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.AuthCache;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.protocol.HttpClientContext;
    import org.apache.http.impl.auth.BasicScheme;
    import org.apache.http.impl.client.BasicAuthCache;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.protocol.HttpContext;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/
     * 
     * 

    And with that, everything is in place – the {@link RestTemplate} will now be able to support the Basic Authentication scheme; a simple usage pattern would be: * *

     * final AuthHttpComponentsClientHttpRequestFactory requestFactory = new AuthHttpComponentsClientHttpRequestFactory(
     *                  httpClient, host, userName, password);
     * final RestTemplate restTemplate = new RestTemplate(requestFactory);
     * 
    * * And the request: * *
     * restTemplate.get("http://localhost:8080/spring-security-rest-template/api/foos/1", Foo.class);
     * 
    * * @author anton */ public class AuthHttpComponentsClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory { protected HttpHost host; @Nullable protected String userName; @Nullable protected String password; public AuthHttpComponentsClientHttpRequestFactory(HttpHost host) { this(host, null, null); } public AuthHttpComponentsClientHttpRequestFactory(HttpHost host, @Nullable String userName, @Nullable String password) { super(); this.host = host; this.userName = userName; this.password = password; } public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host) { this(httpClient, host, null, null); } public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host, @Nullable String userName, @Nullable String password) { super(httpClient); this.host = host; this.userName = userName; this.password = password; } @Override protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(host, basicAuth); // Add AuthCache to the execution context HttpClientContext localcontext = HttpClientContext.create(); localcontext.setAuthCache(authCache); if (userName != null) { BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(userName, password)); localcontext.setCredentialsProvider(credsProvider); } return localcontext; } }

    It is here – in the creation of the HttpContext – that the basic authentication support is built in. As you can see, doing preemptive Basic Authentication with HttpClient 4.x is a bit of a burden: the authentication info is cached and the process of setting up this authentication cache is very manual and unintuitive.

    And with that, everything is in place – the RestTemplate will now be able to support the Basic Authentication scheme; a simple usage pattern would be:

    final AuthHttpComponentsClientHttpRequestFactory requestFactory =
        new AuthHttpComponentsClientHttpRequestFactory(
                    httpClient, host, userName, password);
    final RestTemplate restTemplate = new RestTemplate(requestFactory);
    

    And the request:

    restTemplate.get(
        "http://localhost:8080/spring-security-rest-template/api/foos/1",
        Foo.class);
    

    For an in depth discussion on how to secure the REST Service itself, check out this article.

提交回复
热议问题