自定义ServiceStack OAuth2提供程序

时间:2017-09-27 12:24:53

标签: c# oauth-2.0 servicestack

我们正在尝试与REST服务器通信,该服务器使用自己的OAuth2实现。 这个服务器是由另一家Java公司编写的,所以我对它没有多大影响。 我已经获得了所有必要的信息,例如访问令牌URL,刷新URL,客户端ID,客户端密钥等。我已经可以请求访问令牌,然后使用REST客户端邮递员从该服务器请求其他一些数据。

现在,我想使用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 });
}

1 个答案:

答案 0 :(得分:0)

OAuth提供商要求浏览器重定向到OAuth提供商网站,用户可以在该网站上接受使用该应用的身份验证及其所需的任何权限。一旦用户接受,他们就会重定向回您的ServiceStack应用程序,在那里它将创建一个经过身份验证的用户会话。来自Authenticated User Session的会话ID是在ServiceStack客户端上配置的,用于建立经过身份验证的请求。

以下是一些使用OAuth通过浏览器进行身份验证的示例应用,然后捕获浏览器重定向以提取会话Cookie并在C#服务客户端上对其进行配置,然后他们就可以进行经过身份验证的请求: