現在、サードパーティアプリケーションとローカルレポートシステムの統合に取り組んでいます。基本認証でREST呼び出しを実装しますが、Spring 4.0.0で問題に直面します。うまく機能する簡単な解決策があります。
final RestTemplate restTemplate = new RestTemplate();
final String plainCreds = "username:password";
final byte[] plainCredsBytes = plainCreds.getBytes();
final byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
final String base64Creds = new String(base64CredsBytes);
final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
final HttpEntity<String> request = new HttpEntity<String>(headers);
final ResponseEntity<MyDto> response = restTemplate.exchange("myUrl", HttpMethod.GET, request, MyDto.class);
final MyDto dot = response.getBody();
しかし、これを書き直して、次のようにClientHttpRequestFactoryを使用したいと考えました。
final RestTemplate restTemplate = new RestTemplate(createSecureTransport("username", "password"));
private ClientHttpRequestFactory createSecureTransport(final String username, final String password) {
final HttpClient client = new HttpClient();
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
client.getState().setCredentials(new AuthScope(null, 9090, AuthScope.ANY_REALM), credentials);
return new CommonsClientHttpRequestFactory(client);
}
CommonsClientHttpRequestFactoryクラスがSpring 4.0.0に存在しないため、このコードはコンパイルされていません。誰かがこれに対する代替ソリューションを知っていますか?私はこれでかなり新しいですREST worldしたがって、どんな助けも感謝します。
Spring 4 APIをチェックして、どのクラスが必要なインターフェース、つまり ClientHttpRequestFactory
を実装しているかを確認してください。
Javadocからわかるように、おそらく HttpComponentsClientHttpRequestFactory
が必要です。これは、ApacheのHttpComponentsのクライアントを使用します。これは、古いcommons HttpClient
の後継です。
私はこれが古い質問であることを知っていますが、私はこれに対する答えを自分で探していました。 RestTemplateを構成するときに、RestTemplateインターセプターを追加する必要があります。以下の注釈構成の例:
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(
new FormHttpMessageConverter(),
new StringHttpMessageConverter()
));
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("client", "secret"));
return restTemplate;
}
BasicAuthorizationInterceptor のJavadoc。
私はこれに数時間こだわった。近い将来、誰かを助けるかもしれません。
http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/HttpClientで4.3編集:
Spring 3.0と3.1、そして現在4.xは、Apache HTTPライブラリを非常によくサポートしています:
CommonsClientHttpRequestFactory
は現在と統合されています寿命のあるHttpClient 3.xの終わりHttpComponentsClientHttpRequestFactory
経由( JIRA SPR-618 でサポートを追加)HttpComponentsAsyncClientHttpRequestFactory
経由HttpClient 4とSpring 4で設定を始めましょう。
RestTemplate
には、HTTPリクエストファクトリ(基本認証をサポートするファクトリ-)が必要です。ただし、HttpComponentsClientHttpRequestFactory
のアーキテクチャが設計されているため、既存のRestTemplate
を直接使用することは困難であることが判明します 良好なサポートなし for HttpContext
–パズル。したがって、HttpComponentsClientHttpRequestFactory
をサブクラス化し、createHttpContext
メソッドをオーバーライドする必要があります:( GitHubのsoluvas-frameworkから取得 )
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/
*
* <p>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:
*
* <pre>
* final AuthHttpComponentsClientHttpRequestFactory requestFactory = new AuthHttpComponentsClientHttpRequestFactory(
* httpClient, Host, userName, password);
* final RestTemplate restTemplate = new RestTemplate(requestFactory);
* </pre>
*
* And the request:
*
* <pre>
* restTemplate.get("http://localhost:8080/spring-security-rest-template/api/foos/1", Foo.class);
* </pre>
*
* @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;
}
}
ここで、HttpContext
の作成時に、基本認証サポートが組み込まれています。ご覧のとおり、HttpClient 4.xを使用したプリエンプティブ基本認証の実行は少し負担:認証情報がキャッシュされ、この認証キャッシュの設定は非常に手動で直感的ではないのプロセスです。
これで、すべてが整った-RestTemplate
は基本認証スキームをサポートできるようになります。単純な使用パターンは次のとおりです。
final AuthHttpComponentsClientHttpRequestFactory requestFactory =
new AuthHttpComponentsClientHttpRequestFactory(
httpClient, Host, userName, password);
final RestTemplate restTemplate = new RestTemplate(requestFactory);
そしてリクエスト:
restTemplate.get(
"http://localhost:8080/spring-security-rest-template/api/foos/1",
Foo.class);
RESTサービス自体を保護する方法についての詳細な議論については、 この記事をご覧ください 。
Spring 4.3.1以降、 BasicAuthorizationInterceptor
を使用する簡単な方法があります。これは、RestTemplate
で使用される基礎となるhttpクライアントからも独立しています。
RestTemplateBuilder
from spring-boot を使用してBasicAuthorizationInterceptor
をRestTemplate
に追加する例:
@Configuration
public class AppConfig {
@Bean
public RestTemplate myRestTemplate(RestTemplateBuilder builder) {
return builder
.rootUri("http://my.cool.domain/api/")
.basicAuthorization("login", "password")
.build();
}
}
この方法anymyRestTemplate
Beanインスタンスを使用して送信されたリクエストには、指定された基本認証ヘッダーが含まれます。したがって、同じRestTemplate
Beanインスタンスを使用して外部ドメインにリクエストを送信しないように注意してください。 rootUri
はこれから部分的に保護されますが、RestTemplate
インスタンスを使用してリクエストを行うときは常に絶対URLを渡すことができますので、注意してください!
spring-boot
を使用していない場合は、 this answerに従って、このインターセプターをRestTemplate
に手動で追加することもできます。
複雑さよりもシンプルを好む場合は、ヘッダーを設定するだけです
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString("myuser:mypass".getBytes(Charset.forName("UTF-8"))));
HttpEntity<SomeBody> myRequest = new HttpEntity<>(mybody, headers);
restTemplate.postForEntity(someUrl, myRequest, null);
JDKに同梱されているエンコーディングが冗長すぎる場合は、他にもBase64ライブラリがいくつかあるはずです。
カスタマイズされた残りのテンプレートに基本認証を設定する別のソリューションがあります。
RestTemplate restTemplate = new RestTemplate();
HttpHost proxy =null;
RequestConfig config=null;
String credentials = this.env.getProperty("uname") + ":" + this.env.getProperty("pwd");
String encodedAuthorization = Base64.getEncoder().encodeToString(credentials.getBytes());
Header header = new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedAuthorization);
List<Header> headers = new ArrayList<>();
headers.add(header);
// if we need proxy
if(Boolean.valueOf(env.getProperty("proxyFlag"))){
proxy = new HttpHost(this.env.getProperty("proxyHost"), Integer.parseInt(env.getProperty("proxyPort")), "http");
config= RequestConfig.custom().setProxy(proxy).build();
}else{
config= RequestConfig.custom().build();
}
CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
.setDefaultHeaders(headers).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(factory);
return restTemplate;