Grundlegende Authentifizierung für die REST-API mithilfe von spring restTemplate

83

Ich bin völlig neu in RestTemplate und im Grunde auch in den REST-APIs. Ich möchte einige Daten in meiner Anwendung über die Jira REST-API abrufen, aber 401 Unauthorized zurückerhalten. Gefunden und Artikel über Jira Rest API-Dokumentation, aber ich weiß nicht wirklich, wie ich dies in Java umschreiben soll, da das Beispiel die Befehlszeilenmethode mit Curl verwendet. Ich würde mich über jeden Vorschlag oder Rat zum Umschreiben freuen:

curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"

in Java mit Spring Rest Vorlage. Wobei ZnJlZDpmcmVk eine base64-codierte Zeichenfolge mit dem Benutzernamen: password ist. Vielen Dank.

Shippi
quelle
2
curl unterstützt die sofort einsatzbereite Authentifizierung. Sie müssen lediglich den Benutzernamen und das Kennwort angeben curl -u fred:fred, ohne dass umständliche manuelle Header erforderlich sind. Gleiches gilt für den Frühling.
Divanov

Antworten:

148

Aus dem Beispiel auf dieser Site geht hervor , dass dies der natürlichste Weg ist, indem Sie den Header-Wert eingeben und den Header an die Vorlage übergeben.

Dies ist, um die Überschrift auszufüllen Authorization:

String plainCreds = "willie:p@ssword";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);

Und das ist, um den Header an die REST-Vorlage zu übergeben:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();
Angular University
quelle
1
Danke - das hat bei mir funktioniert. Ich musste darauf hinweisen, dass Sie, wenn Sie die Klasse org.apache.commons.codec.binary.Base64 nicht verwenden möchten und stattdessen die Klasse android Base64 verwenden möchten: import android.util.Base64;, die ersetzen können eine Zeile darüber mit diesem: byte [] base64CredsBytes = Base64.encode (plainCredsBytes, Base64.DEFAULT);
Simon
@jhadesdev Hallo, das hat bei mir funktioniert, als ich eine GET-Anfrage ausgeführt habe. Obwohl es nicht gelingt, eine 403 zu geben, wenn in der Post. Können Sie mir helfen?
Stefano Cazzola
7
Java 8 können Sie Base64.getMimeEncoder (). encodeToString ()
Matt Broekhuis
92

Sie können Spring-Boot RestTemplateBuilder verwenden

@Bean
RestOperations rest(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("user", "password").build();
}

Siehe Dokumentation

(vor SB 2.1.0 war es #basicAuthorization)

Alex
quelle
1
Du hast meinen Tag gerettet. Danke vielmals.
Riccardo.cardin
4
Vielen Dank! Dies ist der schnellste und einfachste Weg.
Rajkishan Swami
1
Ja. Dies ist der schnellste Weg. Es sind keine zusätzlichen Abhängigkeiten erforderlich.
Janath
3
@deprecated seit 2.1.0 zugunsten von #basicAuthentication (String Benutzername, String Passwort)
rjdkolb
1
Dies ist keine gute Lösung, da jeder zugesendeten Anforderung ein Autorisierungsheader hinzugefügt wird RestTemplate.
Attacomsian
22

(vielleicht) der einfachste Weg ohne Spring-Boot zu importieren.

restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));
Leon
quelle
2
Beachten Sie, dass die Verwendung von Interceptors zur Folge hat, dass das Streaming nicht mehr funktioniert. Hier ist der Grund: exchange()-> doExecute(), -> createRequest(), -> InterceptingHttpAccessor.getRequestFactory()(da RestTemplateverlängert InterceptingHttpAccessor). Wenn es Interceptors getRequestFactory()gibt, wird ein zurückgegeben InterceptingClientHttpRequestFactory, wodurch InterceptingClientHttpRequests erstellt wird . Diese erweitern AbstractBufferingClientHttpRequest`, das den Eingabestream in ein Byte [] konvertiert (zur Übergabe an die Interceptors). Ein InputStream wird also nicht wirklich gestreamt.
Mconner
17

Ab Spring 5.1 können Sie verwenden HttpHeaders.setBasicAuth

Erstellen Sie den Header für die Basisautorisierung:

String username = "willie";
String password = ":p@ssword";
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
...other headers goes here...

Übergeben Sie die Header an die RestTemplate:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();

Dokumentation: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html#setBasicAuth-java.lang.String-java.lang.String-

YanivJ
quelle
17

Verweisen Sie TestRestTemplatewie folgt auf die Implementierung von Spring Boot :

https://github.com/spring-projects/spring-boot/blob/v1.2.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/test/TestRestTemplate.java

Beachten Sie insbesondere die Methode addAuthentication () wie folgt:

private void addAuthentication(String username, String password) {
    if (username == null) {
        return;
    }
    List<ClientHttpRequestInterceptor> interceptors = Collections
            .<ClientHttpRequestInterceptor> singletonList(new BasicAuthorizationInterceptor(
                    username, password));
    setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(),
            interceptors));
}

Ebenso können Sie ganz RestTemplateeinfach Ihre eigenen erstellen

durch Vererbung wie TestRestTemplatefolgt:

https://github.com/izeye/samples-spring-boot-branches/blob/rest-and-actuator-with-security/src/main/java/samples/springboot/util/BasicAuthRestTemplate.java

Johnny Lim
quelle
Der erste Link führt zu 404
Zarremgregarrok
14

Es gibt mehrere Möglichkeiten, die grundlegende HTTP-Authentifizierung zum hinzuzufügen RestTemplate.

1. Für eine einzelne Anfrage

try {
    // request url
    String url = "https://jsonplaceholder.typicode.com/posts";

    // create auth credentials
    String authStr = "username:password";
    String base64Creds = Base64.getEncoder().encodeToString(authStr.getBytes());

    // create headers
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + base64Creds);

    // create request
    HttpEntity request = new HttpEntity(headers);

    // make a request
    ResponseEntity<String> response = new RestTemplate().exchange(url, HttpMethod.GET, request, String.class);

    // get JSON response
    String json = response.getBody();

} catch (Exception ex) {
    ex.printStackTrace();
}

Wenn Sie Spring 5.1oder höher verwenden, muss der Berechtigungsheader nicht mehr manuell festgelegt werden. Verwenden Sie headers.setBasicAuth()stattdessen die Methode:

// create headers
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("username", "password");

2. Für eine Gruppe von Anfragen

@Service
public class RestService {

    private final RestTemplate restTemplate;

    public RestService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder
                .basicAuthentication("username", "password")
                .build();
    }

   // use `restTemplate` instance here
}

3. Für jede Anfrage

@Bean
RestOperations restTemplateBuilder(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("username", "password").build();
}

Ich hoffe, es hilft!

Attacomsian
quelle
Beste Antwort. Jeder für seine Art.
Rishi
6

Anstatt wie folgt zu instanziieren:

TestRestTemplate restTemplate = new TestRestTemplate();

Mach es einfach so:

TestRestTemplate restTemplate = new TestRestTemplate(user, password);

Es funktioniert bei mir, ich hoffe es hilft!

Nidham
quelle
TestRestTemplate scheint nicht zu funktionieren, nachdem Spring Boot auf 1.3.x aktualisiert wurde
Vivek Sethi
1
Soll dies nicht für Unit-Tests verwendet werden, nicht für Release-Code?
David Bradley
0

Verwenden Sie setBasicAuthdiese Option, um Anmeldeinformationen zu definieren

HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("myUsername", myPassword);

Erstellen Sie dann die Anfrage nach Ihren Wünschen.

Beispiel:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, 
request, String.class);
String body = response.getBody();
Clairton Luz
quelle
Dublicate of stackoverflow.com/a/53394971 Antwort
Grigory Kislin