2017-09-27 1 views
1

Wir versuchen, mit einem REST-Server zu kommunizieren, der seine eigene OAuth2-Implementierung verwendet. Dieser Server wurde von einer anderen Firma in Java geschrieben, daher habe ich wenig Einfluss darauf. Ich habe alle notwendigen Informationen, wie Access Token URL, URL aktualisieren, Client ID, Client Secret, etc. Ich kann bereits ein Zugriffstoken anfordern und dann einige andere Daten von diesem Server anfordern, mit dem REST-Client Postman.Custom ServiceStack OAuth2-Provider

Jetzt möchte ich den ServiceStack Client (Version 4.5.14) verwenden, um mit diesem Server in C# .NET 4.6.2 zu kommunizieren.

Mein Problem ist: Alle Beispiele, die ich fand, z. http://docs.servicestack.net/authentication-and-authorization#custom-authentication-and-authorization geht entweder um die Server-Seite oder um Authentifizierung gegen Facebook oder Google.

ich implementiert bereits meine eigenen CustomOAuth2Provider, die Zugriffstoken URL Einstellung ConsumerSecret usw. Aber wie sage ich die JsonServiceClient, diesen Provider zu verwenden, bevor die spezifische Anforderung der Ausführung?

Danke, Daniel

Edit:

ich viel Dokumentation und ServiceStack Quellcode lesen, und ich denke, dass meine Hauptprobleme sind die folgenden:

  • ich missbrauchen die ServiceStack-Client um mit einer Nicht-ServiceStack-Anwendung zu kommunizieren, die ich nicht ändern kann.
  • Möglicherweise ist die OAuth2-Implementierung der Drittanbieteranwendung nicht zu 100% korrekt, da sie Autorisierung und Tokenanforderung in derselben Anfrage erwartet.

Aber ich habe es jetzt funktioniert und möchte hier meine Lösung zeigen. Es kann immer noch verbessert werden, z.B. Es verwendet das empfangene Aktualisierungstoken jetzt nicht.

public class ThirdPartyAuthenticator : IDisposable 
{ 
    // TODO: Move to config 
    public const string AccessTokenUrl = ""; 

    public const string ConsumerKey = ""; 
    public const string ConsumerSecret = ""; 

    public const string Username = ""; 
    public const string Password = ""; 

    /// <summary> 
    /// Remember the last response, instance comprehensive so we do not need a new token for every request 
    /// </summary> 
    public static ServiceModel.ThirdPartyOAuth2Response LastOAuthResponse = null; 

    /// <summary> 
    /// This already authenticated client can be used for the data requests. 
    /// </summary> 
    public JsonServiceClient AuthenticatedServiceClient { get; set; } 

    public ThirdPartyAuthenticator() 
    { 
     if (LastOAuthResponse == null || (LastOAuthResponse.ExpiryDateTime < DateTime.Now)) // TODO: Use Refresh token? 
     { 
      // Get token first 
      JsonServiceClient authClient = new JsonServiceClient(AccessTokenUrl); 
      authClient.UserName = ConsumerKey; 
      authClient.Password = ConsumerSecret; 
      authClient.AlwaysSendBasicAuthHeader = true; 

      var request = new ServiceModel.ThirdPartyOAuth2Request(); 
      request.Username = Username; 
      request.Password = Password; 

      // Use the Get URI, because server expects username + password as query parameter 
      LastOAuthResponse = authClient.Post<ServiceModel.ThirdPartyOAuth2Response>(request.ToGetUrl(), request); 
     } 

     // If no exception was thrown, we have a valid token here. 
     AuthenticatedServiceClient = new JsonServiceClient(AccessTokenUrl); 
     AuthenticatedServiceClient.BearerToken = LastOAuthResponse.AccessToken; 
    } 

    public void Dispose() 
    { 
     AuthenticatedServiceClient?.Dispose(); 
    } 
} 

Nutzung:

using (var foo = new ThirdPartyAuthenticator()) 
{ 
    var response = foo.AuthenticatedServiceClient.Get(new ServiceModel.GetMyData() { SomeId = 10 }); 
} 

Antwort

0

OAuth-Anbieter benötigen einen Browser auf die OAuth-Anbieter-Website zu umleiten, wo Benutzer können die Authentifizierung mit dem App akzeptieren und alle Berechtigungen erfordert. Sobald der Benutzer akzeptiert, werden sie zurück zu Ihrer ServiceStack App umgeleitet, wo eine Authentifizierte Benutzersitzung erstellt wird. Die Sitzungs-ID aus der authentifizierten Benutzersitzung ist die auf dem ServiceStack-Client konfigurierte, um authentifizierte Anforderungen einzurichten.

Hier sind einige Beispiele Apps, die OAuth verwenden, um zu Authentifizieren mit einem Browser und den Browser Redirect erfassen die Session-Cookies zu extrahieren und auf dem Client C# Service so konfiguriert, wo sie sind dann in der Lage authentifizierte Anforderungen zu machen:

+0

Vielen Dank für Ihre Antwort, aber ich es immer noch nicht. Ich habe gerade keinen ServiceStack-Host - nur eine Drittanbieter-Serveranwendung. Der Client sollte nur eine OAuth2-Anforderung an diesen Server senden, um ein Zugriffstoken zu erhalten, bevor die Datenanforderung selbst gesendet wird. Ich habe es jetzt funktioniert, indem Sie eine Wrapper-Klasse für den Client schreiben, die die Authentifizierungsanforderung vor der Anforderung selbst aufruft. Ähnlich der Klasse "ServiceStackAuthenticator" im TechStacks-Beispiel. –

+0

@DanielP. Die 'ServiceStackAuthenticator'-Klasse umschließt die [Xamarin.Auth] (https://github.com/xamarin/Xamarin.Auth#xamarinauth), die dafür sorgt, dass das Web-UI geladen, die Benutzereinwilligung erfasst und dann wieder an die OAuth-Weiterleitungs-URL weitergeleitet wird Aufrufen des ServiceStackAuthenticator.Completed-Rückrufs, sodass der Service-Client die authentifizierten Sitzungscookies im Browser extrahieren und sie auf dem Service-Client ausfüllen kann. – mythz

+0

@DanielP. Wenn Sie ein OAuth2-Token abrufen, können Sie es zum Authentifizieren verwenden, indem Sie es auf die Eigenschaft "Authenticate.AccessToken" setzen, wie im [Google OAuth2-Beispiel] zu sehen ist (https://github.com/ServiceStackApps/AndroidJavaChat#login-with- Google-Sign-in-Taste). Dies muss auch in Ihrem Custom AuthProvider implementiert werden. Bitte lesen Sie die [Release Notes dieser Funktion] (http://docs.servicestack.net/releases/v4.5.8#authentication-via-oauth-accesstokens) für Details. – mythz