Looping custom claims on login - Asp.net core - asp.net-core

Our ASP.NET MVC application connects to IdentityServer 3 with the following config and able to access all the custom claims
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = IdentityServerUrl,
ClientId = IdentityClientId,
ResponseType = "id_token token",
Scope = "openid profile myScope",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var newIdentity = new ClaimsIdentity(
n.AuthenticationTicket.Identity.AuthenticationType,
"name",
"myrole");
var userInfoClient = new UserInfoClient(
new Uri(n.Options.Authority + "/connect/userinfo"),
n.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => newIdentity.AddClaim(new Claim(ui.Item1, ui.Item2)));
var sid = n.AuthenticationTicket.Identity.Claims.FirstOrDefault(x => x.Type == "sid");
if (sid != null)
{
newIdentity.AddClaim(new Claim("sid", sid.Value));
}
n.AuthenticationTicket = new AuthenticationTicket(
newIdentity,
n.AuthenticationTicket.Properties);
}
}
});
Now we want to upgrade and connect to IdentityServer 3 with .net core
We tried below code but I am not getting the sure how to loop through all the custom claims
.AddOpenIdConnect("oidc", options =>
{
options.Authority = IdentityClientUrl;
options.ClientId = IdentityClientId;
options.ResponseType = OpenIdConnectResponseType.IdTokenToken;
options.Scope.Clear();
options.Scope.Add("profile");
options.Scope.Add("openid");
options.Scope.Add("email");
options.Scope.Add("myScope");
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "myrole"
};
options.SaveTokens = true;
options.ClaimActions.MapUniqueJsonKey("myrole", "myrole", "string");
});
In the existing approach, i am able to get all the claims from userInfo, so I can loop and add everything.
In the asp.net core - however I can map them using ClaimActions, eachone at a time. Is there any way I can loop throug all of them and add all of them - say I don't know the claimType!
Any help please?

You can try this to map all the claims using the MapAllExcept method, like:
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce");

Related

Multiple configurations for one OpenIdConnect service

I have two URLs that can be directed to my web app. Depending on the URL, I want to change what OpenIdConect (OIDC) configuration to use. I want to be able to do this without restarting the app. This requirement came after the web app was created and now needs to support two URLs.
Let's say the URLs are:
internal-mywebapp.company.com
mywebapp.company.com
The original code in Startup.cs : ConfigureServices :
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = oidcOptions.CookieSchemeName;
options.Authority = oidcOptions.AuthServerUrl;
options.ClientId = "ExternalClientId";
options.ClientSecret = oidcOptions.ClientSecret;
options.ResponseType = oidcOptions.ResponseType;
options.SaveTokens = true;
foreach (var claim in oidcOptions.RequestClaims)
{
options.Scope.Add(claim);
}
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.DeleteClaim("sid");
options.Events.OnRedirectToIdentityProvider =
EventsOnRedirectToIdentityProvider(applicationOptions);
options.Events.OnRemoteFailure = EventsOnRemoteFailure();
})
Now, my thinking is to add code the the Configure method and, if the URL starts with 'internal', use the configuration for 'internal'. I'm newer to configuring a web app to use authentication providers so I'm not too aware of the possibilities.
One thing that came up when researching this was to add a second OIDC block to AddOpenIdConnect like this and then do something in the Configure method to switch to the needed configuration :
.AddOpenIdConnect("oidc-external", options =>
{
options.SignInScheme = oidcOptions.CookieSchemeName;
options.Authority = oidcOptions.AuthServerUrl;
options.ClientId = "ExternalClientId";
options.ClientSecret = oidcOptions.ClientSecret;
options.ResponseType = oidcOptions.ResponseType;
options.SaveTokens = true;
foreach (var claim in oidcOptions.RequestClaims)
{
options.Scope.Add(claim);
}
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.DeleteClaim("sid");
options.ClaimActions.MapUniqueJsonKey("userLdapid", "userLdapid");
options.ClaimActions.MapUniqueJsonKey("fpUserRole", "fpUserRole");
options.ClaimActions.MapUniqueJsonKey("userType", "userType");
options.Events.OnRedirectToIdentityProvider =
EventsOnRedirectToIdentityProvider(applicationOptions);
options.Events.OnRemoteFailure = EventsOnRemoteFailure();
})
.AddOpenIdConnect("oidc-internal", options =>
{
options.SignInScheme = oidcOptions.CookieSchemeName;
options.Authority = oidcOptions.AuthServerUrl;
options.ClientId = "InternalClientId";
options.ClientSecret = oidcOptions.ClientSecret;
options.ResponseType = oidcOptions.ResponseType;
options.SaveTokens = true;
foreach (var claim in oidcOptions.RequestClaims)
{
options.Scope.Add(claim);
}
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.DeleteClaim("sid");
options.ClaimActions.MapUniqueJsonKey("userLdapid", "userLdapid");
options.ClaimActions.MapUniqueJsonKey("fpUserRole", "fpUserRole");
options.ClaimActions.MapUniqueJsonKey("userType", "userType");
options.Events.OnRedirectToIdentityProvider =
EventsOnRedirectToIdentityProvider(applicationOptions);
options.Events.OnRemoteFailure = EventsOnRemoteFailure();
});
I could be overlooking a different approach as posts I have found sort of hint that this can be done but nothing quite fit.
#PabloRecalde : I'm not sure if was entirely clear of what I wanted.
To rectify this, we decided to split out the same code base into two separate instances with the help of our CI/CD pipeline. We were trying to use the same instance and figure out a way to switch between two OIDC based on the host name for each request. This proved difficult.

ASP.NET JWT: Signature validation failed. No security keys were provided to validate the signature

I've been making a web api in F#, mostly following this guide: https://www.blinkingcaret.com/2017/09/06/secure-web-api-in-asp-net-core/. However, I've been getting this error whenever I try to hit an authenticated endpoint in my aspnet webapi:
Failed to validate the token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiciIsImV4cCI6IjE1MjI2MzUwNDMiLCJuYmYiOiIxNTIyNTQ4NjQzIn0.VofLygSMitkmEsTBFNG-7-3jMAZYkyvfwc2UIs7AIyw.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500: Signature validation failed. No security keys were provided to validate the signature.
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__6.MoveNext()
I've found similar issues linked here, but none whose resolution helped me. My Startup.fs looks like:
type Startup private () =
new (configuration: IConfiguration) as this =
Startup() then
this.Configuration <- configuration
// This method gets called by the runtime. Use this method to add services to the container.
member this.ConfigureServices(services: IServiceCollection) =
// Add framework services
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(fun options ->
options.TokenValidationParameters = TokenValidationParameters (
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
ValidateLifetime = false, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5.0) //5 minute tolerance for the expiration date
) |> ignore
) |> ignore
services.AddMvc() |> ignore
services.AddSwaggerGen (fun c -> c.SwaggerDoc("v1", Swagger.Info())) |> ignore
services.AddCors() |> ignore
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
app.UseExceptionHandler(
fun options ->
options.Run(
fun context ->
let ex = context.Features.Get<IExceptionHandlerFeature>()
match ex.Error with
| HttpCodedException (code, message) ->
printfn "code: %i, msg: %s" (int code) message
context.Response.StatusCode <- int code
context.Response.WriteAsync(message)
| exn -> raise (exn)
)
) |> ignore
// let cors = Action<CorsPolicyBuilder> (fun builder -> builder.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod() |> ignore)
app.UseCors(fun policy ->
policy.AllowAnyHeader()
.AllowAnyOrigin()
.AllowCredentials()
.AllowAnyMethod()
.Build() |> ignore
) |> ignore
app.UseAuthentication() |> ignore
app.UseMvc() |> ignore
member val Configuration : IConfiguration = null with get, set
I've tried turning off basically all of the validation, so I'm confused why this is still failing. If it's helpful, the place where I generate the tokens looks like:
let GenerateToken (username) =
let claims = [|
Claim (ClaimTypes.Name, username)
Claim (JwtRegisteredClaimNames.Exp, DateTimeOffset(DateTime.Now.AddDays(1.0)).ToUnixTimeSeconds().ToString())
Claim (JwtRegisteredClaimNames.Nbf, DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString())
|]
let cred =
new SigningCredentials(
SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
SecurityAlgorithms.HmacSha256
)
let token = JwtSecurityToken(JwtHeader(cred), JwtPayload(claims))
JwtSecurityTokenHandler().WriteToken(token)
Hoping someone can see what I'm doing wrong.
Finally figured this out. F# doesn't use = for assignment, it uses <-. So needed to change my service AddAuthenticaton call to:
services.AddAuthentication(fun options ->
options.DefaultScheme <- JwtBearerDefaults.AuthenticationScheme
options.DefaultAuthenticateScheme <- JwtBearerDefaults.AuthenticationScheme
options.DefaultChallengeScheme <- JwtBearerDefaults.AuthenticationScheme
).AddJwtBearer(fun options ->
options.TokenValidationParameters <- TokenValidationParameters (
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = false,
IssuerSigningKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
ValidateLifetime = false, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5.0), //5 minute tolerance for the expiration date
ValidateActor = false,
ValidateTokenReplay = false
)
) |> ignore
Now everything works fine.
This has been working well for me.
JWT Authentication settings
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("thisKeyIs32CharactersLong1234567"))
ValidateIssuer = true,
ValidIssuer = "MyIssuer",
ValidateAudience = true,
ValidAudience = "MyAudience",
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
And then to create the actual token
var handler = new JwtSecurityTokenHandler();
var securityToken = handler.CreateToken(
new SecurityTokenDescriptor
{
Issuer = "MyIssuer",
Audience = "MyAudience",
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes("thisKeyIs32CharactersLong1234567")), SecurityAlgorithms.HmacSha512Signature),
Subject = new ClaimsIdentity(
new[] {
new Claim(ClaimTypes.Name, "My Name"),
new Claim(ClaimTypes.Sid, "My UID"),
new Claim(ClaimTypes.GroupSid, "My GID")
},
Expires = DateTime.Now + TimeSpan.FromMinutes("30")
});
// Save token
handler.WriteToken(securityToken);
Hope it helps.

IdentityServer4 client - Refreshing access tokens on CookieAuthenticationEvents

I am trying to use refresh token when the access token expires. A similar so question is answered here. And a sample code to renew token by an action
And i end up with the following code in the startup.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
//ExpireTimeSpan = TimeSpan.FromSeconds(100),
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;
var logger = loggerFactory.CreateLogger(this.GetType());
var now = DateTimeOffset.UtcNow;
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);
if (timeElapsed > timeRemaining)
{
var httpContextAuthentication = x.HttpContext.Authentication;//Donot use the HttpContext.Authentication to retrieve anything, this cause recursive call to this event
var oldAccessToken = await httpContextAuthentication.GetTokenAsync("access_token");
var oldRefreshToken = await httpContextAuthentication.GetTokenAsync("refresh_token");
logger.LogInformation($"Refresh token :{oldRefreshToken}, old access token:{oldAccessToken}");
var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);
var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);
logger.LogInformation("Refresh token requested. " + tokenResult.ErrorDescription);
if (!tokenResult.IsError)
{
var oldIdToken = await httpContextAuthentication.GetTokenAsync("id_token");
var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;
var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};
var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });
var info = await httpContextAuthentication.GetAuthenticateInfoAsync("Cookies");
info.Properties.StoreTokens(tokens);
await httpContextAuthentication.SignInAsync("Cookies", info.Principal, info.Properties);
}
x.ShouldRenew = true;
}
else
{
logger.LogInformation("Not expired");
}
}
}
});
The client setup is as follows
AllowAccessTokensViaBrowser = true,
RefreshTokenUsage = TokenUsage.ReUse,
RefreshTokenExpiration = TokenExpiration.Sliding,
AbsoluteRefreshTokenLifetime = 86400,
AccessTokenLifetime = 10,
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Reference
After successfully login, i am getting a 401 for every other request. And the log says
[Identity Server]2017-07-04 10:15:58.819 +01:00 [Debug]
"TjpIkvHQi../cfivu6Nql5ADJJlZRuoJV1QI=" found in database: True
[Identity Server]2017-07-04 10:15:58.820 +01:00 [Debug]
"reference_token" grant with value:
"..9e64c1235c6675fcef617914911846fecd72f7b372" found in store, but has
expired.
[Identity Server]2017-07-04 10:15:58.821 +01:00 [Error] Invalid
reference token. "{ \"ValidateLifetime\": true,
\"AccessTokenType\": \"Reference\", \"TokenHandle\":
\"..9e64c1235c6675fcef617914911846fecd72f7b372\" }"
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Token is
invalid.
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Creating
introspection response for inactive token.
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Information] Success
token introspection. Token status: "inactive", for API name: "api1"
Any help would by highly appreciated
UPDATE:
Basically, when the token expires i get a System.StackOverflowException on the following line
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
UPDATE 2:
Do not use HttpContext.Authentication to retrieve anything. Check my answer below to find the working implementaion
I was working on this for last two days and could not make this work. Funnily, after posting the question here, within 2 hours I make it working :)
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;
var now = DateTimeOffset.UtcNow;
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);
WriteMessage($"{timeRemaining} and elapsed at {timeElapsed}");
if (timeElapsed > timeRemaining)
{
var oldAccessToken = x.Properties.Items[".Token.access_token"];
var oldRefreshToken = x.Properties.Items[".Token.refresh_token"];
WriteMessage($"Refresh token :{oldRefreshToken}, old access token {oldAccessToken}");
var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);
var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);
if (!tokenResult.IsError)
{
var oldIdToken = x.Properties.Items[".Token.id_token"];//tokenResult.IdentityToken
var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;
var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};
var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });
x.Properties.StoreTokens(tokens);
WriteMessage($"oldAccessToken: {oldAccessToken}{Environment.NewLine} and new access token {newAccessToken}");
}
x.ShouldRenew = true;
}
}
}
Basically httpContextAuthentication.GetTokenAsync make this recursive, for that reason StackOverflowException occured.
Please let me know if this implementation has any issue

Missing user_metadata in userInfo of auth0

For authentication I am using Auth0 AuthenticationApi. In Account Controller, I need to fetch the user_metadata but it's missing. Any alternative to fetch the user_metadata?
AuthenticationApiClient client = new AuthenticationApiClient(new Uri($"https://{_auth0Options.Domain}/"));
var authenticateResponse = await client.GetTokenAsync(new ResourceOwnerTokenRequest
{
ClientId = _auth0Options.ClientId,
ClientSecret = _auth0Options.ClientSecret,
Scope = "openid",
Realm = _auth0Options.Connection,
Username = vm.EmailAddress,
Password = vm.Password
});
var user = await client.GetUserInfoAsync(authenticateResponse.AccessToken);
if (user.UserMetadata != null)
{
// Giving error...any alternative to access the userMetaData ?
}
Yes, as far as I see it now, the legacy call still works. However, I don't have a non-legacy solution yet :(
using (var client = GetClient())
{
var jObject = new JObject(new JProperty("id_token", id_token));
var response = await client.PostAsJsonAsync("tokeninfo", jObject);
if (response.IsSuccessStatusCode)
{
var userProfileJson = JObject.Parse(await response.Content.ReadAsStringAsync());
retVal.user_id = userProfileJson.Value<string>("user_id");
retVal.email = userProfileJson.Value<string>("email");
retVal.user_name = userProfileJson.Value<string>("nickname");
if (userProfileJson.Value<string>("created_at") != null)
{
retVal.created_at = userProfileJson.Value<DateTime>("created_at");
}
var exists = userProfileJson.TryGetValue("user_metadata", out JToken meta);

Update claims after login with identityserver3 2.1.1

We need to update users claims after they log in to our website. This is caused by changes in the users licenses done by another part of our system.
However I am not able to comprehend how to update the claims without logout/login.
Rigth now this is our client setup
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
//user validation host
Authority = UrlConstants.BaseAddress,
//Client that the user is validating against
ClientId = guid,//if not convertet to Gui the compare from the server fails
RedirectUri = UrlConstants.RedirectUrl,
PostLogoutRedirectUri = UrlConstants.RedirectUrl,
ResponseType = "code id_token token",
Scope = "openid profile email roles licens umbraco_api umbracoaccess",
UseTokenLifetime = false,
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
_logger.Info("ConfigureAuth", "Token valdidated");
var id = n.AuthenticationTicket.Identity;
var nid = new ClaimsIdentity(
id.AuthenticationType,
Constants.ClaimTypes.GivenName,
Constants.ClaimTypes.Role);
// get userinfo data
var uri = new Uri(n.Options.Authority + "/connect/userinfo");
var userInfoClient = new UserInfoClient(uri,n.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2)));
var licens = id.FindAll(LicenseScope.Licens);
nid.AddClaims(licens);
// keep the id_token for logout
nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
n.AuthenticationTicket = new AuthenticationTicket(
nid,
n.AuthenticationTicket.Properties);
_logger.Info("ConfigureAuth", "AuthenticationTicket created");
},
RedirectToIdentityProvider = async n =>
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token").Value;
_logger.Debug("ConfigureAuth", "id_token for logout set on request");
_logger.Debug("ConfigureAuth", "Old PostLogoutRedirectUri: {0}", n.ProtocolMessage.PostLogoutRedirectUri.ToString());
n.ProtocolMessage.IdTokenHint = idTokenHint;
var urlReferrer = HttpContext.Current.Request.UrlReferrer.ToString();
if (!urlReferrer.Contains("localhost"))
{
n.ProtocolMessage.PostLogoutRedirectUri = GetRedirectUrl();
}
else
{
n.ProtocolMessage.PostLogoutRedirectUri = urlReferrer;
}
_logger.Debug("ConfigureAuth", string.Format("Setting PostLogoutRedirectUri to: {0}", n.ProtocolMessage.PostLogoutRedirectUri.ToString()));
}
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
{
n.ProtocolMessage.RedirectUri = GetRedirectUrl2();
n.ProtocolMessage.AcrValues = GetCurrentUmbracoId();
_logger.Debug("ConfigureAuth", string.Format("Setting RedirectUri to: {0}", n.ProtocolMessage.RedirectUri.ToString()));
}
},
}
});
We get our custom claims in SecurityTokenValidated
var licens = id.FindAll(LicenseScope.Licens);
nid.AddClaims(licens);
I do not follow how to get this without doing a login? Any help is highly appreciated.
That's a reminder that you should not put claims into tokens that might change during the lifetime of the session.
That said - you can set a new cookie at any point in time.
Reach into the OWIN authentication manager and call the SignIn method. Pass the claims identity that you want to serialize into the cookie.
e.g.
Request.GetOwinContext().Authentication.SignIn(newIdentity);