Custom OAuth2 Provider Protocol Error

I’m trying to authenticate against our apps identityserver but get an error message by ServiceStack after logging in to our application.

Error response:

{"ResponseStatus":{"ErrorCode":"ProtocolException","Message":"Unexpected OAuth authorization response received with callback and client state that does not match an expected value.","StackTrace":"[Authenticate: 2016-11-17 13:25:25]:\n[REQUEST: {provider:myprovider}]\nDotNetOpenAuth.Messaging.ProtocolException: Unexpected OAuth authorization response received with callback and client state that does not match an expected value.\r\n   at DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(Boolean condition, String unformattedMessage, Object[] args)\r\n   at DotNetOpenAuth.OAuth2.WebServerClient.ProcessUserAuthorization(HttpRequestBase request)\r\n   at ServiceStack.Authentication.OAuth2.OAuth2Provider.ProcessUserAuthorization(WebServerClient authClient, AuthorizationServerDescription authServer, IServiceBase authService)\r\n   at ServiceStack.Authentication.OAuth2.OAuth2Provider.Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)\r\n   at ServiceStack.Auth.AuthenticateService.Authenticate(Authenticate request, String provider, IAuthSession session, IAuthProvider oAuthConfig)\r\n   at ServiceStack.Auth.AuthenticateService.Post(Authenticate request)\r\n   at lambda_method(Closure , Object , Object )\r\n   at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)","Errors":[]}}

My web.config looks like this:

  <add key="oauth.myprovider.RedirectUrl" value="http://localhost:56000/" />
  <add key="oauth.myprovider.CallbackUrl" value="http://localhost:56000/auth/myprovider" />
  <add key="oauth.myprovider.ClientId" value="myid" />
  <add key="oauth.myprovider.ClientSecret" value="mysecret" />

My provider looks like this

public class MyOAuth2Provider : OAuth2Provider
{
    public const string Name = "myprovider";

    public const string Realm = "https://joelintegrationtest.cloudapp.net/MainTenantManager/oauth/authorize";

    public MyOAuth2Provider(IAppSettings appSettings)
        : base(appSettings, Realm, Name)
    {
        this.AuthorizeUrl = "https://joelintegrationtest.cloudapp.net/MainTenantManager/oauth/authorize";
        this.AccessTokenUrl = "https://joelintegrationtest.cloudapp.net:9070/MainTenantManager/connect/token";
        this.UserProfileUrl = this.UserProfileUrl ?? "?";

        if (this.Scopes.Length == 0)
        {
            this.Scopes = new[] {
                "default"
            };
        }
    }

    public override 

    protected override Dictionary<string, string> CreateAuthInfo(string accessToken)
    {
        //var url = this.UserProfileUrl.AddQueryParam("access_token", accessToken);
        //string json = url.GetJsonFromUrl();
        //var obj = JsonObject.Parse(json);
        //var emails = obj.Object("emails");
        //var authInfo = new Dictionary<string, string>
        //{
        //    { "user_id", obj["id"] },
        //    { "username", emails["account"] },
        //    { "email", emails["preferred"] },
        //    { "name", obj["name"] },
        //    { "first_name", obj["first_name"] },
        //    { "last_name", obj["last_name"] },
        //    { "gender", obj["gender"] },
        //    { "locale", obj["locale"] }
        //};
        return new Dictionary<string, string>();
    }

Note OAuth2Provider uses DotNetOpenAuth for its implementation which isn’t supported in HttpListener Hosts.

The error sounds similar to this DotNetOpenAuth issue http://stackoverflow.com/q/22677983/85785 in which case one thing you can try is to stop DNOA setting a state automatically by specifying your own, e.g:

new MyOAuth2Provider(..) {
    AuthServerFilter = authServer => 
        authServer.AuthorizationTracker = DotNetOpenAuthTokenManager()
}

Hmm I can´t see a property named AuthorizationTracker , I have only:

  • TokenEndpoint
  • ProtocolVersion
  • Version

as fields on authServer.

But if I understand you correctly, things should “just work” if I do not self host but instead run via iis?

Edit: Nevermind, I guess you mean AuthClientFilter and not AuthServerFilter

Yeah looks like it should be added to AuthClientFilter, e.g:

new MyOAuth2Provider(..) {
    AuthClientFilter = authClient => 
        authClient.AuthorizationTracker = DotNetOpenAuthTokenManager()
}

Worked like a charm, I also had to install an invalid dev certificate to be trusted then everything worked. Thank you.

1 Like