具有clientIdentifier的GetClientAccessToken被NetworkCredential覆盖为null

时间:2012-10-15 14:07:45

标签: oauth oauth-2.0 dotnetopenauth

我一直试图让GetClientAccessToken流程与最新版本4.1.0(通过nuget)一起使用,我控制所有三方:客户端,授权服务器和资源服务器。

我开始构建原型的情况是Windows客户端应用程序(我的客户端 - 最终它将是WinRT,但它现在只是一个单独的MVC 4应用程序以保持简单),以及WebAPI中的一组资源项目。我现在在同一个WebAPI项目中将部分授权服务器作为控制器公开。

每次(似乎无论客户端类型如UserAgentClient还是WebServerClient)我尝试GetClientAccessToken,当请求到达auth服务器时,请求中没有clientIdentifier,因此请求失败:

2012-10-15 13:40:16,333 [41   ] INFO   {Channel} Prepared outgoing AccessTokenFailedResponse (2.0) message for <response>: 
error: invalid_client
error_description: The client secret was incorrect.

我已经通过源调试到DNOA,基本上我在客户端上建立的凭据被NetworkCredential.ApplyClientCredential ClientBase.RequestAccessToken内部消灭了。如果我将clientIdentifier修改为合理的东西,我可以跟踪我的其余代码并查看正确的查找/检查,所以我非常有信心auth服务器代码没问题。

我的测试客户端目前看起来像这样:

public class AuthTestController : Controller
{
    public static AuthorizationServerDescription AuthenticationServerDescription
    {
        get
        {
            return new AuthorizationServerDescription()
            {
                TokenEndpoint = new Uri("http://api.leave-now.com/OAuth/Token"),
                AuthorizationEndpoint = new Uri("http://api.leave-now.com/OAuth/Authorise")
            };
        }
    }

    public async Task<ActionResult> Index()
    {
        var wsclient = new WebServerClient(AuthenticationServerDescription, "KieranBenton.LeaveNow.Metro", "testsecret");

        var appclient = new DotNetOpenAuth.OAuth2.UserAgentClient(AuthenticationServerDescription, "KieranBenton.LeaveNow.Metro", "testsecret");
        var cat = appclient.GetClientAccessToken(new[] { "https://api.leave-now.com/journeys/" }); 

        // Acting as the Leave Now client we have access to the users credentials anyway
        // TODO: CANNOT do this without SSL (turn off the bits in web.config on BOTH sides)
        /*var state = client.ExchangeUserCredentialForToken("kieranbenton", "password", new[] { "https://api.leave-now.com/journeys/" });

        // Attempt to talk to the APIs WITH the access token
        var resourceclient = new OAuthHttpClient(state.AccessToken);
        var response = await resourceclient.GetAsync("https://api.leave-now.com/journeys/");
        string sresponse = await response.Content.ReadAsStringAsync();*/

        // A wrong one
        /*var wresourceclient = new OAuthHttpClient("blah blah");
        var wresponse = await wresourceclient.GetAsync("https://api.leave-now.com/journeys/");
        string wsresponse = await wresponse.Content.ReadAsStringAsync();

        // And none
        var nresourceclient = new HttpClient();
        var nresponse = await nresourceclient.GetAsync("https://api.leave-now.com/journeys/");
        string nsresponse = await nresponse.Content.ReadAsStringAsync();*/

        return Content("");
    }
}

我无法弄清楚如何防止这种情况,或者如果设计不正确我做错了什么。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:2)

如您所见,NetworkCredentialApplicator会从传出邮件中清除client_id和secret,但会将其应用为HTTP Authorization标头。但是,HttpWebRequest在出路时清除该标头,并且仅在服务器响应HTTP错误和WWW-Authenticate标头时才恢复其值。如果你问我,在.NET的部分,这是非常奇怪的行为,在第一个出站请求上取消凭证。

因此,如果来自auth服务器的响应是正确的(至少是.NET客户端期望的那样)那么请求将会两次出去,并且第二次工作。否则,您可以尝试使用PostParameterApplicator