I have questions upon using the new ASP.Net OpenID Connect framework while adding new Claims during the authentication pipeline as shown in the code below. I'm not sure just how much 'magic' is happening behind the scenes. I think most of my questions center around not knowing much about OWIN authentication middleware as opposed to OpenID Connect.
Q1. Should I be manually setting HttpContext.Current.User
and Thread.CurrentPrincipal
from OwinContext.Authentication.User
?
Q2. I want the ability to add object types to claims like I used to with System.IdentityModel.Claims.Claim
. The new System.Security.Claims.Claim
class only accepts string values?
Q3. Do I need to use the new SessionSecurityToken
wrapper for my ClaimsPrincipal
in System.Security.Claims.CurrentPrincipal
for serializing into a cookie - I am using app.UseCookieAuthentication(new CookieAuthenticationOptions());
but now sure what that does exactly in terms of maintaining any additional claims I added during SecurityTokenValidated
event?
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = (context) =>
{
// retriever caller data from the incoming principal
var UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
var db = new SOSBIADPEntities();
var user = db.DomainUser.FirstOrDefault(b => (b.EntityName == UPN));
if (user == null)
{
// the caller was not a registered user - throw to block the authentication flow
throw new SecurityTokenValidationException();
}
var applicationUserIdentity = new ClaimsIdentity();
applicationUserIdentity.AddClaim(new Claim(ClaimTypes.Name, UPN, ""));
applicationUserIdentity.AddClaim(new Claim(ClaimTypes.Sid, user.ID.ToString(CultureInfo.InvariantCulture)));
var applications =
db.ApplicationUser
.Where(x => x.ApplicationChild != null && x.DomainUser.ID == user.ID)
.Select(x => x.ApplicationChild).OrderBy(x => x.SortOrder);
applications.ForEach(x =>
applicationUserIdentity.AddClaim(new Claim(ClaimTypes.System, x.ID.ToString(CultureInfo.InvariantCulture))));
context.OwinContext.Authentication.User.AddIdentity(applicationUserIdentity);
var hasOutlook = context.OwinContext.Authentication.User.HasClaim(ClaimTypes.System, "1");
hasOutlook = hasOutlook;
HttpContext.Current.User = context.OwinContext.Authentication.User;
Thread.CurrentPrincipal = context.OwinContext.Authentication.User;
var usr = HttpContext.Current.User;
var c = System.Security.Claims.ClaimsPrincipal.Current.Claims.Count();
return Task.FromResult(0);
},
}
}
);
}
Is there a specific reason for which you are adding a new ClaimsIdentity
?
The simplest way of doing what you are aiming at is to retrieve the ClaimsIdentity
that was generated by validating the incoming token, via ClaimsIdentity claimsId = context.AuthenticationTicket.Identity;
once you have it, just add claims to it. The rest of the middleware will take care of serializing it in the session cookie along with everything else, place the result in the current ClaimsPrincipal
, and all those other things you appear to be trying to do manually.
HTH
V.