oAuth Client - change response_type - asp.net-core

How do I change response_type to token in Startup.cs in "OAuth client"?
The server only recognizes the request with the response_type equal to token.
services.AddOAuth("OurServer", config => {
config.ClientId = "client_id";
config.ClientSecret = "client_secret";
config.CallbackPath = "/oauth/callback";
config.AuthorizationEndpoint = "https://localhost:44382/oauth/authorize";
config.TokenEndpoint = "https://localhost:44382/oauth/token";
config.SaveTokens = true;
config.Events = new OAuthEvents()
{
OnCreatingTicket = context =>
{
var accessToken = context.AccessToken;
var base64payload = accessToken.Split('.')[1];
var bytes = Convert.FromBase64String(base64payload);
var jsonPayload = Encoding.UTF8.GetString(bytes);
var claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonPayload);
foreach (var claim in claims)
{
context.Identity.AddClaim(new Claim(claim.Key, claim.Value));
}
return Task.CompletedTask;
}
};
});

By default the OAuth authentication handler uses response_type='code' internally and does not let you change that- reference here.
If you wish to change that you have to create a custom OAuth authentication handler and override BuildChallengeUrl() where you can set your response_type.
You can see how you can use your custom handler here: link

Related

Asp.net core 6 mvc : Authorize controller methods with JWT token from external API

I am building a .Net core 6 mvc website which will interact with an API built by an external party. Amongst other things, the user authentication is handled by the API. The API responds with a JWT bearer token once user is authenticated and I need to tie that in to my website to Authorize controller methods.
At this point I call the API and successfully receive the token as expected, however after days of struggling to get [Authorize] to work in the controllers with the token, I am completely lost and hoping for some guidance.
After scrapping multiple iterations of code, this what I currently have.... (excuse the mess)
public async Task<TokenResponse> LoginAsync(string email, string password)
{
var userLogin = new UserLogin
{
Email = email,
Password = password
};
string encoded = System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(email + ":" + password));
var client = new RestClient("api location");
var request = new RestRequest();
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic " + encoded);
var response = await client.GetAsync(request);
var result = JsonConvert.DeserializeObject<TokenResponse>(response.Content);
return result;
}
public async Task<IActionResult> LoginPostAsync(LoginViewModel viewModel)
{
var tokenResponse = await _userManagementService
.LoginAsync(viewModel.Email, viewModel.Password);
if (!string.IsNullOrEmpty(tokenResponse.access_token))
{
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(tokenResponse.access_token);
var jti = jwtSecurityToken.Claims.First(claim => claim.Type == "jti").Value;
var account_type = jwtSecurityToken.Claims.First(claim => claim.Type == "account_type").Value;
var userId = jwtSecurityToken.Claims.First(claim => claim.Type == "user_id").Value;
var email = jwtSecurityToken.Claims.First(claim => claim.Type == "email").Value;
var iss = jwtSecurityToken.Claims.First(claim => claim.Type == "iss").Value;
string[] userRoles = { "admin", "candidate",};
HttpContext context = new DefaultHttpContext();
var accessToken = tokenResponse.access_token;
//var userClaims = new List<Claim>()
// {
// new Claim("email", email),
// new Claim("account_type", account_type),
// new Claim("jti", jti),
// };
//var userIdentity = new ClaimsIdentity(userClaims, "User Identity");
//var userPrincipal = new ClaimsPrincipal(new[] { userIdentity });
//context.SignInAsync(userPrincipal);
//Response.Cookies.Append(
// Constants.XAccessToken,
// tokenResponse.access_token, new CookieOptions
// {
// Expires = DateTimeOffset.UtcNow.AddMinutes(1),
// HttpOnly = true,
// SameSite = SameSiteMode.Strict
// });
//return new AuthenticateResponse(user, token);
SetJWTCookie(accessToken);
return RedirectToAction("index", "Home", new { area = "CandidateDashboard" });
}
return Unauthorized();
}
Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(config =>
{
config.SaveToken = true;
config.RequireHttpsMetadata = false;
config.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuer = "issue data",
ValidateIssuerSigningKey = false,
};
config.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Cookies["Bearer"];
return Task.CompletedTask;
}
};
});
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult Index()
{
return View();
}
This is the what I see in dev console.
--bearer error="invalid_token", error_description="the signature key was not found"
Payload from Bearer
{
"iss": "data here",
"exp": 1647323406,
"nbf": 1647319746,
"iat": 1647319806,
"jti": "e8f297d3-blah blah",
"account_type": "candidate",
"user_id": "2342342342",
"email": "email#email.com"
}
The core problem is that AddJwtBearer by default only trusts token issued by someone it trusts (the issuer) because it needs to verify the signature of the token. You of course want to verify it so a hacker doesn't send fake/forged tokens to your API.
So either you need to add that
.AddJwtBearer(opt =>
{
opt.Authority = "https://issuer.com"
In this way, AddJwtBearer will download the public signing key automatically for you.
Or you need to add the public signing key manually to AddJwtBearer.
see https://devblogs.microsoft.com/dotnet/jwt-validation-and-authorization-in-asp-net-core/

User.Identity.Name is empty with JWT when method is no decorated with Authorize in Asp.NET Core 3.0 API Controller

I have a Web Api project in .net core 3.1 and I have added JwT authentication.
The authentication and authorization work very well, but I need to get the UserId in every request. When the method is decorated with Authorize attribute, this works well.
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IEnumerable<WeatherForecast> Get()
{
string user = User.Identity.Name; //Get a value
//Do something
}
However I have some method which authentication is not required, but if an authenticated user make a request, I would like to get the userId, but in this case, user.Identity.Name is always null.
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
string user = User.Identity.Name; //null
//Do somwthing
}
My configuration in statur file is:
private void ConfigureJwt(IServiceCollection services)
{
//Add Auth scheme
services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
AuthSettings authSettings = Configuration.GetSection("AuthSettings").Get<AuthSettings>();
JwtIssuerOptions jwtIssuerOptions = Configuration.GetSection("JwtIssuerOptions").Get<JwtIssuerOptions>();
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtIssuerOptions.Issuer,
ValidAudience = jwtIssuerOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authSettings.SecretKey))
};
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
//When method is no decorated with Authorize, it not working
var userId = int.Parse(context.Principal.Identity.Name);
return System.Threading.Tasks.Task.CompletedTask;
}
};
});
services.AddTransient<ITokenService, TokenService>(x =>
{
return new TokenService(Configuration);
});
}
TokenService class:
public class TokenService : ITokenService
{
IConfiguration configuration = null;
AuthSettings authSettings = null;
public TokenService(IConfiguration _configuration)
{
configuration = _configuration;
authSettings = configuration.GetSection("AuthSettings").Get<AuthSettings>();
}
public string GenerateAccessToken(IEnumerable<Claim> claims, ref JwtIssuerOptions jwtIssuerOptions)
{
//var authSettings = configuration.GetSection(nameof(AuthSettings));
//var authSettings = configuration.GetSection("EmailSettings").Get<AuthSettings>();
jwtIssuerOptions = configuration.GetSection("JwtIssuerOptions").Get<JwtIssuerOptions>();
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authSettings.SecretKey));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken (
issuer: jwtIssuerOptions.Issuer,
audience: jwtIssuerOptions.Audience,
claims: claims,
expires: jwtIssuerOptions.Expiration,
//expires: DateTime.Now.AddMinutes(5),
signingCredentials: signinCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
return tokenString;
}
public string GenerateRefreshToken()
{
var randomNumber = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomNumber);
return Convert.ToBase64String(randomNumber);
}
}
public ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
{
TokenValidationParameters tokenValidationParameters = GetValidationParameters();
var tokenHandler = new JwtSecurityTokenHandler();
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out securityToken);
var jwtSecurityToken = securityToken as JwtSecurityToken;
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
throw new SecurityTokenException("Invalid token");
return principal;
}
private TokenValidationParameters GetValidationParameters()
{
var tokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false, //you might want to validate the audience and issuer depending on your use case
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authSettings.SecretKey)),
ValidateLifetime = false //here we are saying that we don't care about the token's expiration date
};
return tokenValidationParameters;
}
}
AuthController
[HttpPost, Route("login")]
public async Task<IActionResult> Login([FromBody] LoginModel loginModel)
{
if (loginModel == null)
return BadRequest("Invalid client request");
var sessionInfo = await userBo.LoginUser(loginModel);
if (sessionInfo == null)
return Unauthorized();
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, sessionInfo.User.BusinessEntityId.ToString()),
new Claim(ClaimTypes.Role, sessionInfo.User.RoleCode)
};
JwtIssuerOptions tokeOptions = null;
var accessToken = tokenService.GenerateAccessToken(claims, ref tokeOptions);
var refreshToken = tokenService.GenerateRefreshToken();
await tokenBo.SaveToken(
new Token()
{
BusinessEntityId = sessionInfo.Person.BusinessEntityId,
RefreshToken = refreshToken,
RefreshTokenExpiryTime = tokeOptions.Expiration
}
);
sessionInfo.TokenInfo = new TokenInfo()
{
AccessToken = accessToken,
RefreshToken = refreshToken
};
return Ok(sessionInfo);
}
}
Thank you for your help!
As far as I know, if the controller doesn't need authorize, it will not add the user information into pipeline claims, so the user name is always null.
To solve this issue, I suggest you could try to add a custom middleware to check if the request contains the Authorization header. If it contains you could get the username and add it into http context item.
Then you could directly get the username in the api controller instead of getting it from User.Identity.Name.
More details, you could refer to below codes:
Add below middleware into startup.cs Configure method:
app.Use(async (context, next) =>
{
// you could get from token or get from session.
string token = context.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(token))
{
var tok = token.Replace("Bearer ", "");
var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(tok);
var jti = jwttoken.Claims.First(claim => claim.Type == ClaimTypes.Name).Value;
context.Items.Add("Username", jti);
}
await next();
});
Controller get the username:
object value;
ControllerContext.HttpContext.Items.TryGetValue("Username", out value);
var username = value.ToString();
Result:
After changing an application from using cookie-based authentication to using JWT I ran into this problem. You can work around it — sort of — by creating an authorization handler with no requirements thus allowing anonymous users access. The ASP.NET pipeline doesn't know which requirements will be required so it will provide the credentials of the user if they are present in the request. The end result is that anonymous users are allowed but if credentials are provided they will be available.
The trivial requirement:
class RequireNothing : IAuthorizationRequirement { }
And the handler:
class RequireNothingHandler : AuthorizationHandler<RequireNothing>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RequireNothing requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
If the request contains credentials they will become available in the User object but the requirement also allow anonymous users access.
To use the requirement you can create a policy (and also add the handler to the DI container):
services
.AddAuthorization(options => options
.AddPolicy("AlsoAllowAnonymous", policy => policy
.AddRequirements(new RequireNothing())))
.AddSingleton<IAuthorizationHandler, RequireNothingHandler>();
To combine authenticated and anonymous access you decorate the action or controller with the attribute:
[Authorize(Policy = "AlsoAllowAnonymous")]
Unfortunately, this might not work so well. If you are using a long-lived JWT refresh tokens and short-lived access tokens that are refreshed when a 401 challenge is received there will be no challenge after the access token expires and the user will access the end-point anonymously possibly resulting in a degraded user experience even though the user has authenticated and has a refresh token to prove that.
This problem is not unique to using an authorization handler and you get more control by providing two different end-points: one for anonymous users and another one for authenticated users. You need some extra logic on the client side to select the correct API for things to work out right though.

how to made a method to validate a cookie authentication? asp.net core 3.1

I've tried make a method to to validate a cookie authentication but appear this error:
Error
I've tried use this:
public int CookieValidation()
{
int answer = 0;
string CookieSession = HttpContext.Session.GetString("SesionSecondApp");
if(!String.IsNullOrEmpty(CookieSession))
{
answer = 1;
}
return answer;
}
}
I made a cookie authentication:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "SesionSecondApp";
options.ExpireTimeSpan = TimeSpan.FromDays(7);
options.Cookie.SameSite = SameSiteMode.Lax;
});
Use this claims:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.Role, role),
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var props = new AuthenticationProperties();
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, props);
In the browser, cookie stores the authentication configuration that has been added in the server. SesionSecondApp cannot be obtained from the session here, because you did not configure session.
The correct way to get SesionSecondApp is this code.
public int CookieValidation()
{
int answer = 0;
var getCookie = "";
HttpContext.Request.Cookies.TryGetValue("SesionSecondApp", out getCookie);
//...
return answer;
}
Result:

INVALID_TICKET Receiving From CAS in Asp.Net Core2.2

I have to use SSO with CAS Login. When I put user name and password then it goes to CAS server for validate the credential, after a successful validation I find out Authentication is true and now I want to validate receive ticket and need some information which comes in XML from CAS.
But when I send the ticket to serviceValidate URL, then every time I receive INVALID_TICKET Error.
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationFailure code='INVALID_TICKET'>
Ticket 'ST-48062-BNWXlqUWFg97PF4UZZKw-cas.identity.ucsb.edu' not recognized
</cas:authenticationFailure>
</cas:serviceResponse>
Please help me. I am providing my code Please check and let me know where I am wrong.
Waiting for favorable response.
In startup's ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddScoped<iUserService, UserService>();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o =>
{
o.LoginPath = new PathString("/login");
o.AccessDeniedPath = new PathString("/access-denied");
o.Cookie = new CookieBuilder
{
Name = ".AspNetCore.CasiEval"
};
o.Events = new CookieAuthenticationEvents
{
OnSigningIn = async context =>
{
var username = context.Principal.Identity.Name;
var userSvc = context.HttpContext.RequestServices.GetRequiredService<iUserService>();
var ticket_val = context.HttpContext.Request.Query["ticket"].ToString();
var state_val= context.HttpContext.Request.Query["state"].ToString();
string serviceUrl = $"https%3A%2F%2Flocalhost%3A44357%2FHome%2FIndex%3F";
string baseUrl = string.Empty;
baseUrl = "https://cas.application.com/cas/serviceValidate?";
string casUrl = $"{baseUrl}service={serviceUrl}&ticket={ticket_val}";
using (var httpClient = new HttpClient())
{
// Define Headers
httpClient.DefaultRequestHeaders.Accept.Clear();
// Add an Accept header for JSON format.
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await httpClient.GetAsync(casUrl);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var result = response.Content.ReadAsStringAsync();
}
}
ClaimsIdentity identity = new ClaimsIdentity();
context.Principal.AddIdentity(identity);
await Task.Delay(100);
return;// Task.FromResult(0);
}
};
})
.AddCAS(o =>
{
o.CasServerUrlBase = Configuration["CasBaseUrl"]; // Set in `appsettings.json` file.
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.SaveTokens = true;
o.CallbackPath = new PathString("/Home/Index");
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Double OWIN authentication not working together

For my website I'm making an integration with a 3rd party authentication provider, using OWIN OpenId, to allow visitors to sign up/sign in/sign out. "Second"
I also have a test environment for my application where all code changes are tested before pushing these changes to production. I shield the test environment from public access with another 3rd party authentication provider, using OWIN OpenId as well "First". Only authenticated visitors can visit the test environment website.
Now the problem is that these both work standalone, but I can't seem to combine them. What I'm trying to achieve is that I can access the test environment by authenticating with First, and then, as a regluar visitor, authenticate with Second to see content designed for registered visitors.
Here's what I'm doing:
Both authnetication providers work with cookie authentication, but I gave them a different AuthenticationType to keep them apart.
if (IsEnabled("First"))
app.SetDefaultSignInAsAuthenticationType("First");
else
app.SetDefaultSignInAsAuthenticationType("Second");
// Configure First.
if (IsEnabled("First")) {
app.UseCookieAuthentication(First.CookieAuthenticationOptions); // AuthenticationType is set to "First" in these options.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = First.AADClientId,
Authority = First.Authority,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context => { ... },
RedirectToIdentityProvider = context => { ... }
},
AuthenticationType = "First"
});
app.Map($"{First.Path}/login", config =>
{
config.Run(context =>
{
context.Authentication.Challenge(new AuthenticationProperties
{ RedirectUri = First.ReturnUrl, IsPersistent = true },
"First"
);
context.Response.StatusCode = 401;
return context.Response.WriteAsync(string.Empty);
});
});
}
// Configure Second.
app.UseCookieAuthentication(Second.CookieAuthenticationOptions); // AuthenticationType is set to "Second" in these options.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = x => ...,
RedirectToIdentityProvider = x =>
{
var mgr = x.Options.ConfigurationManager as PolicyConfigurationManager;
if (x.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;
}
else
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;
}
var redirectUri = Second.ReturnPath;
x.ProtocolMessage.RedirectUri = redirectUri;
x.ProtocolMessage.PostLogoutRedirectUri = redirectUri;
},
SecurityTokenValidated = x => ...
},
Scope = "openid",
ResponseType = "id_token",
ReturnUri = Second.ReturnUri,
ClientId = Second.ClientId,
ConfigurationManager = GetConfigurationManager()
AuthenticationType = configuration.AuthenticationType
});
app.Map(Second.LoginPath, config =>
{
// Trigger unauthorized so that active authentication will redirect to active directory.
config.Run(context =>
{
// Set policy in context to mitigate null ref exception in Startup.Auth OnRedirectToIdentityProvider
context.Authentication.Challenge(
new AuthenticationProperties(new Dictionary<string, string>
{
{"PolicyId", Second.LoginPolicyId}
})
{
IsPersistent = true,
RedirectUri = returnUrl
}, "Second");
context.Response.StatusCode = 401;
// Middleware will redirect us instead of using this output.
return context.Response.WriteAsync(string.Empty);
});
});
app.Map(Second.ReturnPath, config =>
{
config.Use((context, next) =>
{
// In case of login, we will never get here because we will get redirected by middleware.
context.Response.Redirect("/");
return Task.FromResult(0);
});
});
When First is enabled, this allows me to do
var identity = HttpContext.Current.GetOwinContext.Authentication.AuthenticateAsync("Second").Result?.Identity;
on subsequent requests and have a ClaimsIdentity. But when First is enabled, for some reason the above Result is null.
I've noticed that when I enable both First and Second, and set the DefaultSignInAsAuthenticationType to "Second", it is First that doesn't work anymore. If I enable both First and Second, and browse the site with a previous authentication cookie of First, everything works just fine.
I'm guessing that the return method, that somewhere sets an authentication cookie needs some reference of AuthenticationType, but I don't know where to do that.
What am I missing?
The trick is to add the AuthenticationType to TokenValidationParameters when configuring Second, like so:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = x => ...,
RedirectToIdentityProvider = x =>
{
var mgr = x.Options.ConfigurationManager as PolicyConfigurationManager;
if (x.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;
}
else
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;
}
var redirectUri = Second.ReturnPath;
x.ProtocolMessage.RedirectUri = redirectUri;
x.ProtocolMessage.PostLogoutRedirectUri = redirectUri;
},
SecurityTokenValidated = x => ...
},
Scope = "openid",
ResponseType = "id_token",
ReturnUri = Second.ReturnUri,
ClientId = Second.ClientId,
ConfigurationManager = GetConfigurationManager(),
AuthenticationType = configuration.AuthenticationType,
// ADD THIS TO MAKE IT WORK:
TokenValidationParameters = new TokenValidationParameters
{
AuthenticationType = configuration.AuthenticationType
}
});