5

I have an ASP.NET Core 2 MVC app using identity server 3 with Hybrid flow with an intention of fetching access tokens also which i can use further for accessing API's, sometimes I am redirected to the IDP login page and after entering username and password i am redirected back to the MVC app, but it is failing randomly.

I have the following configuration

 services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;

            })
             .AddOpenIdConnect(options =>
             {
                 options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                 options.Authority = authConfig.GetValue<string>("Authority");
                 options.RequireHttpsMetadata = false;
                 options.ClientId = authConfig.GetValue<string>("ClientId");
                 options.ClientSecret = authConfig.GetValue<string>("ClientSecret");
                 options.ResponseType = "code id_token token";
                 options.SaveTokens = true;
                 options.GetClaimsFromUserInfoEndpoint = false;
                 options.TokenValidationParameters = new
                 TokenValidationParameters
                 {
                     NameClaimType = ClaimTypes.Name,
                     RoleClaimType = ClaimTypes.Role
                 };
                 options.Events = new OpenIdConnectEvents
                 {
                     OnRemoteFailure = context =>
                     {
                         context.HttpContext.Response.Redirect($"/Error?RequestId=4000&errormessage={context.Failure?.Message }");
                         context.HandleResponse();
                         return Task.FromResult(0);
                     },
                     OnRedirectToIdentityProvider = context =>
                     {
                         //TODO: Get IdentityProvider value for Multiple subscribers and not from config
                         var idp = authConfig.GetValue<string>("IdentityProvider");
                         var acrValues = new List<string>();

                         if (!string.IsNullOrWhiteSpace(idp))
                             acrValues.Add($"idp:{idp}");

                         if (acrValues.Count > 0)
                             context.ProtocolMessage.AcrValues = string.Join(" ", acrValues);

                         //if (context.ProtocolMessage.RequestType != OpenIdConnectRequestType.Logout)
                         //{
                         //    if (!CurrentEnvironment.IsDevelopment() &&
                         //        context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                         //    {
                         //        // in widget iframe skip prompt login screen
                         //        context.ProtocolMessage.Prompt = "none";
                         //    }
                         //    return Task.FromResult(0);
                         //}

                         var idTokenHint = context.HttpContext.User.FindFirst("id_token");
                         if (idTokenHint != null)
                             context.ProtocolMessage.IdTokenHint = idTokenHint.Value;

                         return Task.FromResult(0);
                     }

and the configuration on Identity server for the client is like

    "ClientName": "SampleApp",
    "ClientId": "sample.app.mvc",
    "Flow": 2,
    "RedirectUris": ["https://localhost:44368/signin-oidc"],
    "PostLogoutRedirectUris": ["https://localhost:44368/"],
        "PrefixClientClaims": true,
    "RequireConsent": false,
    "AllowedScopes": 
    [
        "openid",
        "profile",
        "roles",
        "CustomScope"
    ],
    "Claims": [{
        "Type": "subscriberId",
        "Value": "dcbe85c6-05b6-470d-b558-289d1ae3bb15"
    }],
"ClientSecrets": [{
        "Secret": "tudc73K2y7pnEjT2"
    }],

    "IdentityTokenLifetime": 300,
    "AccessTokenLifetime": 3600,
    "AuthorizationCodeLifetime": 300,
    "EnableLocalLogin": true
}

I keep hitting the error invalid_grant most of the times when i try in browsers. Can you please tell me what part of the configuration is incorrect?

CSharped
  • 1,247
  • 4
  • 20
  • 49
  • What do you mean by most of the times? And also - do you have Identity Server logging enabled? If not - do it, it will help you a lot. – m3n7alsnak3 Apr 23 '18 at 21:23
  • I have enabled logging..I see an error there which says invalid Authorization code – CSharped Apr 24 '18 at 01:39
  • This is by no means a full answer but there is a solution that uses identity server 4 with .net core 2.0, https://www.codeproject.com/Articles/1205745/Identity-Server-with-ASP-NET-Core. I am curious if this helps you because I do not see EnableLocalLogin. –  May 02 '18 at 21:44

1 Answers1

3

I have found what the issue is here.

It wasn't happening because of any configuration mentioned above. But because of the fact that I was using InMemory store for AuthorizationCode store, and also my identity server was deployed on Azure and had 2 instances.

CSharped
  • 1,247
  • 4
  • 20
  • 49
  • Was this on the Identity Server or the client app? Where in the code did you make the change? Also, did you reduce the number of instances Identity Server was running on or not? – Stuart Frankish Aug 10 '19 at 22:40
  • Error was thrown by identity server and was resolved when I reduced the number of instances to 1 – CSharped Aug 11 '19 at 01:55
  • We had this issue as well. Identityserver3 was dividing it's traffic between an productionslot (80%) and a Canaryslot (20%). After moving all the traffic to the productionslot the issue appeared to be resolved. Still somewhat strange because we have the ARRAffinity-cookie enabled on Azure – Rob Dec 24 '19 at 09:12