我們正在嘗試與使用自己的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 });
}
謝謝你的回答,但我還是不明白這一點。我現在沒有ServiceStack主機 - 只是第三方服務器應用程序。 在發送數據請求本身之前,客戶端應僅向此服務器發送OAuth2請求以獲取訪問令牌。 我現在通過爲客戶端編寫一個包裝類,它在請求本身之前調用了認證請求。 與TechStacks示例中的「ServiceStackAuthenticator」類相似。 –
@DanielP。 'ServiceStackAuthenticator'類包裝了[Xamarin.Auth](https://github.com/xamarin/Xamarin.Auth#xamarinauth),它負責加載Web UI,捕獲用戶的同意,重定向回到oauth重定向url調用ServiceStackAuthenticator.Completed回調,以便服務客戶端可以在瀏覽器中提取經過身份驗證的會話cookie並將其填充到服務客戶端上。 – mythz
@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