使用DotNetOpenAuth登录Amazon返回(400)Bad Request

时间:2014-06-19 15:18:52

标签: .net oauth-2.0 dotnetopenauth login-with-amazon

我在.NET 3.5解决方案上使用DotNetOpenAuth为我们的客户提供社交登录。我成功实施了Facebook,谷歌和Twitter,但我被困在亚马逊。我正在为OAuth 2.0提供程序使用相同的代码,但是当亚马逊加载登录屏幕时,我输入了用户名和密码,当我点击登录时,我的代码在调用ProcessUserAuthorization()时崩溃,引发以下错误:DNOA抱怨:“发送时发生错误直接留言或得到答复。“和内部异常:“远程服务器返回错误:(400)错误请求。”。 这是我的方法:

private static AuthenticationDetailsType LoginOauth2(string[] scope = null, Uri return_uri = null)
    {
        try
        {
            // get provider name
            string provider_name = ((LoginProviders)providerID).ToString();

            var response = new AuthenticationDetailsType();

            // get configuration details
            var token_endpoint = ConfigurationManager.AppSettings[provider_name + "TokenEndPoint"];
            var auth_endpoint = ConfigurationManager.AppSettings[provider_name + "AuthEndPoint"];
            var app_key = ConfigurationManager.AppSettings[provider_name + "AppKey"];
            var app_secret = ConfigurationManager.AppSettings[provider_name + "AppSecret"];

            // instantiate a server
            var server = new AuthorizationServerDescription
            {
                TokenEndpoint = new Uri(token_endpoint),
                AuthorizationEndpoint = new Uri(auth_endpoint)
            };

            // instantiate a client
            var client = new WebServerClient(server)
            {
                ClientIdentifier = app_key,
                ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(app_secret)
            };

            IAuthorizationState auth_state = client.ProcessUserAuthorization();

            if (auth_state == null)
            {
                client.RequestUserAuthorization(scope, return_uri);
            }
            else
            {
                response =  new AuthenticationDetailsType
                {
                    auth_provider = providerID,
                    auth_token = auth_state.AccessToken,
                    auth_token_secret = null,
                    user_id = null
                };
            }
            return response;
        }
        catch (Exception ex)
        {
            ErrorLogger.ErrorLog.WriteError("Error on loging in with provider " + provider_name + " error: "+ ex.StackTrace.ToString());
            return null;
        }
    }

这是我的配置键:

<add key="amazonTokenEndPoint" value="https://api.amazon.com/auth/o2/token"/>
<add key="amazonAuthEndPoint" value="https://www.amazon.com/ap/oa"/>
<add key="amazonAppKey" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
<add key="amazonAppSecret" value="xxxxxxxxxxxxxxxxxxxxxxx"/>
<add key="amazonDetailsRequestEndPoint" value="https://api.amazon.com/user/profile"/>
<add key="amazonReturnUri" value="https://localhost/SocialLogin.aspx?providerid=x"/>

这就是我称之为这种方法的方式:

return LoginOauth2(new string[] { "profile" }, new Uri(System.Configuration.ConfigurationManager.AppSettings["amazonReturnUri"]));

点击亚马逊登录界面上的登录后,在此方法的第二次调用时抛出异常。

我尝试了google-ing但我找不到资源指向我的问题。

感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

我的解决方案是从来自亚马逊的请求中删除查询字符串中的额外参数。我只是在IIRF中放了一个重写规则,我删除了参数范围。

例如。必须https://mydomain.com/login?code=xxx&scope=xxx&state=xxx https://mydomain.com/login?code=xxx&state=xxx

这是必需的,因为DotNetOpenAuth正在使用传入请求来请求授权令牌但是将范围保留在查询字符串中并且亚马逊不喜欢这样。接受的参数是:grant_type,code,client_id,client_secret和redirect_uri,任何额外的,你的请求将获得400响应(错误的请求)。 我尝试编译自己的DotNetOpenAuth dll但没有运气,因为它们已经签名,我需要使用.net 3.5的代码。

作为结论,对具有其他参数的令牌的任何请求都将返回400响应。

我不知道这是否是最佳选择,但这适用于我的情况。