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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With