2017-09-27 147 views
1

我們正在嘗試與使用自己的OAuth2實現的REST服務器進行通信。 這臺服務器是由另一家公司用Java編寫的,所以我對它沒有太大影響。 我已經獲得了所有必要的信息,例如Access Token URL,Refresh URL,Client Id,Client Secret等。我已經可以請求一個訪問令牌,然後使用REST客戶端Postman從此服務器請求一些其他數據。自定義ServiceStack OAuth2提供程序

現在我想使用ServiceStack客戶端(版本4.5.14)在C#.NET 4.6.2中與此服務器進行通信。

我的問題是:我找到的所有例子,例如http://docs.servicestack.net/authentication-and-authorization#custom-authentication-and-authorization是關於服務器端或關於Facebook或Google的身份驗證。

我已經實現了我自己的CustomOAuth2Provider,設置訪問令牌URL,ConsumerSecret等 但我怎麼告訴JsonServiceClient,使用此提供程序,執行特定的請求之前?

謝謝 丹尼爾

編輯:

我看了很多文件和ServiceStack源代碼的,而且我覺得我的主要問題有以下幾點:

  • 我濫用ServiceStack客戶端與我無法修改的非ServiceStack應用程序進行通信。
  • 也許第三方應用程序的OAuth2實現不是100%正確的,因爲它期望在相同請求中使用授權和令牌請求。

但我現在正在工作,並想在這裏顯示我的解決方案。 它仍然可以改進,例如它現在不使用收到的刷新令牌。

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(); 
    } 
} 

用法:

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

回答

0

OAuth的提供商需要一個瀏覽器重定向到的OAuth提供者的網站,用戶可以與應用程序,它要求任何權限,可以接受身份驗證。一旦用戶接受,他們將被重定向回您的ServiceStack應用程序,在那裏它將創建一個Authenticated User Session。來自Authenticated User Session的會話ID是ServiceStack客戶端上配置的用於建立經過驗證的請求的內容。

這裏有一些例子應用其使用OAuth使用瀏覽器進行身份驗證,然後捕獲瀏覽器重定向到提取會話cookie和C#的服務客戶,他們是那麼能夠做出驗證請求,將其配置:

+0

謝謝你的回答,但我還是不明白這一點。我現在沒有ServiceStack主機 - 只是第三方服務器應用程序。 在發送數據請求本身之前,客戶端應僅向此服務器發送OAuth2請求以獲取訪問令牌。 我現在通過爲客戶端編寫一個包裝類,它在請求本身之前調用了認證請求。 與TechStacks示例中的「ServiceStackAuthenticator」類相似。 –

+0

@DanielP。 'ServiceStackAuthenticator'類包裝了[Xamarin.Auth](https://github.com/xamarin/Xamarin.Auth#xamarinauth),它負責加載Web UI,捕獲用戶的同意,重定向回到oauth重定向url調用ServiceStackAuthenticator.Completed回調,以便服務客戶端可以在瀏覽器中提取經過身份驗證的會話cookie並將其填充到服務客戶端上。 – mythz

+0

@DanielP。如果您設法檢索OAuth2令牌,您可以通過將其設置爲Authenticate.AccessToken屬性來將其用於Authenticate,如[Google OAuth2示例]所示(https://github.com/ServiceStackApps/AndroidJavaChat#login-with-谷歌-登入-按鈕)。這也需要在您的自定義AuthProvider中實現,請閱讀[此功能的發行說明](http://docs.servicestack.net/releases/v4.5.8#authentication-via-oauth-accesstokens)以獲取詳細信息。 – mythz

相關問題