.netoauth-2.0dotnetopenauthlogin-with-amazon

Login with Amazon using DotNetOpenAuth returns (400) Bad Request


I'm using DotNetOpenAuth on a .NET 3.5 solution to provide social login for our customers. I implemented successfully Facebook, Google and Twitter but I'm stuck at Amazon. I'm using same code for OAuth 2.0 providers but when Amazon loads login screen, I put user and password and when I click login my code crashes on calling ProcessUserAuthorization(), throwing following errors: DNOA complains about: "Error occurred while sending a direct message or getting the response." and inner exception: "The remote server returned an error: (400) Bad Request.". Here is my method:

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

And this are my config keys:

<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"/>

This is how I call this method:

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

The exception is thrown at second call of this method, after clicking the Login on Amazon's login screen.

I tried google-ing but I couldn't find resources pointing at my problem.

Thanks for help :)


Solution

  • My solution was to remove extra parameters from query string from request coming from Amazon. I just put a rewrite rule in IIRF where I removed the parameter scope.

    eg. https://mydomain.com/login?code=xxx&scope=xxx&state=xxx will have to be https://mydomain.com/login?code=xxx&state=xxx.

    This is needed as DotNetOpenAuth is using incoming request to request for an authorization token but keeps the scope in the query string and Amazon doesn't like this. Accepted parameters are: grant_type, code, client_id, client_secret and redirect_uri, anything extra and your request will get 400 response (bad request). I tried compiling my own DotNetOpenAuth dlls but with no luck as they are signed and I need to use code for .net 3.5.

    As a conclusion any request for a token that has other parameters than the ones accepted by Amazon will return a 400 response.

    I don't know if this is the best option but this works in my case.