get signature from TokenValidatedContext - c#

I'm using the Microsoft.AspNetCore.Authentication.JwtBearer and System.IdentityModel.Tokens.Jwt packages for my .NET Core project.
When configuring the services I'm adding logic to the OnTokenValidated event.
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(jwtBearerOptions =>
{
// ... set TokenValidationParameters ...
jwtBearerOptions.Events = new JwtBearerEvents()
{
OnTokenValidated = (tokenValidatedContext) =>
{
JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
string tokenWithoutSignature = jwtSecurityTokenHandler.WriteToken(tokenValidatedContext.SecurityToken);
// ... full token from request? ...
}
};
});
Since I know the context only returns me the token without the signature I would like to know how I can
either get the full token with signature
or the signature additionally to add it to the tokenWithoutSignature string
If this is not possible:
I'm generating new tokens this way
public string GenerateAccessToken(IDictionary<string, object> payload)
{
SymmetricSecurityKey symmetricSecurityKey = new SymmetricSecurityKey(Convert.FromBase64String("secret from config"));
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
{
Claims = payload,
Expires = DateTime.Now, // value from config
SigningCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature)
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
string token = tokenHandler.WriteToken(securityToken);
return token;
}
Maybe I can either retrieve
the token string without the signature
only the signature
within this method?
If nothing works:
Since I kow a bearer token always contains three parts like
header.payload.signature
I could split the string segments to an array, take the first and second element from the array and create a new string of
firstString + . + secondString
That should give me the token without the signature. Are there any better ideas to cut off the signature from a full token?
Why do I want to achieve this?
This question is based on this one
Security token from TokenValidatedContext from the OnTokenValidated event listener is missing last string segment
I'm working with access and refresh tokens. During validation, I have to compare the token from the request with the token from the database. The token in the database contains the signature too. So I'm facing the same problem as linked above.
That's why I thought about multiple solutions and wrote them down here. If the TokenValidatedContext is not able to return me the signature it seems I have to store the JWT to the database without the signature. And also for this case, I need to separate the signature from the generated JWT.
Without using refresh tokens I only store the maximum session lifetime of a user to the database. The flow is based on this idea
Only store the time of the JWT with the highest lifetime to the database instead of the whole JWT
With using refresh tokens I came up with the following flow. Since you know that the OnTokenValidated handles the validation logic the following logic is additional. I have a database table with
username | access_token | refresh_token | refresh_token_expires_at
and the primary key is a composite key of username + access_token. Refresh tokens are just some random strings generated like so
public string GenerateRefreshToken()
{
var randomNumber = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomNumber);
return Convert.ToBase64String(randomNumber);
}
}
and that's why I'm storing an additional expiration date to it. It should be able to expire after some time.
Signing in
Store the generated access and refresh token and its expiration time for a user to the database. Either store the full access token or the access token without signature to the database (depends on the solution of this question).
Hitting a protected endpoint
Check if that access token for that user exists in the database.
Hitting the refresh endpoint
Check if the database refresh token has expired. If not, compare this one with the refresh token from the request. If everything is fine, remove the old access and refresh token from the database and store the new generated access and refresh token to the database.
Signing out
Remove that access and its connected refresh token from the database.

I don't quite understand why you do all this, but if all you need is the original token, you can use one of these:
o.Events = new JwtBearerEvents
{
OnTokenValidated = (context) =>
{
var securityToken = (System.IdentityModel.Tokens.Jwt.JwtSecurityToken)context.SecurityToken;
var token = securityToken.RawData; // "ey...."
var tokenHeader = securityToken.RawHeader; // "ey...."
var tokenPayload = securityToken.RawPayload; // "ey...."
var tokenSignatur = securityToken.RawSignature; // "ey...."
var fullBearerHeader = context.Request.Headers["Authorization"]; // "Bearer ey..."
return Task.CompletedTask;
}
};
You probably want to make the code a bit more safe with regards to type casting etc., but it should give you the token.

Why do you want to manipulate the token? If it is just to Validate the token you can use below code.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
//ValidIssuer = Configuration["Issuer"],
//ValidAudience = Configuration["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Key"]))
};
});
and
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}

Related

How to validate id_token received by asp.net mvc OWIN from azure AD B2C

We have a security requirement that we must validate the id token we receive from Azure AD B2C. We need to validate these at the minimum
customSecurityLevel, audience, not before and "expiration time", issuer, nonce
Looking asp.net MVC OWIN middleware, I noticed that that OpenIdConnectAuthenicationOptions provides these:
return new OpenIdConnectAuthenticationOptions
{
...
Notifications = new OpenIdConnectAuthenticationNotifications //Specifies events which the OpenIdConnectAuthenticationMiddleware invokes to enable developer control over the authentication process.
{
AuthenticationFailed = this.AuthenticationFailed,
RedirectToIdentityProvider = this.RedirectToIdentityProvider,
AuthorizationCodeReceived = this.OnAuthorizationCodeReceived,
},
TokenValidationParameters = new TokenValidationParameters
{
SaveSigninToken = true, // Important to save the token in boostrapcontext
ValidateAudience = true, // Validate the Audience
ValidateIssuer = true, // Validate the Issuer
ValidateLifetime = true, // Validate the tokens lifetime
ValidIssuer = Issuer, // The issuer to be validated
ValidAudience = ClientId, // The Audience to be validated
},
};
Being quiet new to OWIN, I'm trying to understand below:
Does OWIN middleware magically validates the token we receive from Azure AD B2C or do we need to manually perform validation per this:
https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-manual-jwt-validation/
At what point in time should token validation should occur i.e. AuthorizationCodeReceived event or on redirect controller/action (page) that's configured on Azure AD B2C redirect URL?
We need to validate more attributes that TokenValidationParameters supports e.g. customSecurityAttribute we send on initial payload. Is there a way to extend this?
How do we parse the token that we receive from Azure AD B2C using OWIN?
Any code sample would be handy.
TO make your question simpler.
The idea behind token is to parse the token and get 3 parts from the token
-Header : contain information about in which algorithm the token haven been encrypted
-Payload : information about the user
-Signature: it's the calculation of encryption of ( Header + Payload) using the Azure certificate or( your identity provider).
Next step the user sends request to your back-end along with JWT.
your back-end will parse the token and get certificate type then will preform HTTP request to your identity provider to get certificate
Next your back-end will construct the certificate option and try to do encryption for ( header + Payload) came from your token the output string must be exactly same Signature you received in the token from your front-end.
If every thing is okay
now your back-end will start validating other attributes like Audience, Issuer
if you configure your token to validate the Audience means your front-end required to provide token contain Audience(Application ID) exactly same your back-end as well as for issuer.
the question now how my back-end knows about certificate?
Azure AD using OpenID connect, More information here
since you configred you tenant in backend the auth packge will make a call to https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration to get the details about your identity provider
and one important link as will is ("jwks_uri": "https://login.microsoftonline.com/common/discovery/keys") where the signature hosted.
You can read and search more how to validate certificate JWT and check this
https://codereview.stackexchange.com/questions/70005/authentication-with-jwt
moving to part 2 of validate more attributes.
Since you are using OpenIdConnect, the package has class called OpenIdConnectEvents that you can trigger events and do what ever you want like this
.AddOpenIdConnect(o =>
{
//Additional config snipped
o.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
//Get user's immutable object id from claims that came from Azure AD
string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
//Get EF context
var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();
//Check is user a super admin
bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == oid);
if (isSuperAdmin)
{
//Add claim if they are
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role, "superadmin")
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
};
});
moving to part 3
parsing token in javascript
function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
return JSON.parse(window.atob(base64));
};
parsing token in C#
use this libary https://www.jsonwebtoken.io/
try {
string jsonPayload = JWT.JsonWebToken.Decode(token, secretKey);
Console.WriteLine(jsonPayload);
} catch (JWT.SignatureVerificationException) {
Console.WriteLine("Invalid token!");
}
or manual
var jwtHandler = new JwtSecurityTokenHandler();
var jwtInput = txtJwtIn.Text;
//Check if readable token (string is in a JWT format)
var readableToken = jwtHandler.CanReadToken(jwtInput);
if(readableToken != true)
{
txtJwtOut.Text = "The token doesn't seem to be in a proper JWT format.";
}
if(readableToken == true)
{
var token = jwtHandler.ReadJwtToken(jwtInput);
//Extract the headers of the JWT
var headers = token.Header;
var jwtHeader = "{";
foreach(var h in headers)
{
jwtHeader += '"' + h.Key + "\":\"" + h.Value + "\",";
}
jwtHeader += "}";
txtJwtOut.Text = "Header:\r\n" + JToken.Parse(jwtHeader).ToString(Formatting.Indented);
//Extract the payload of the JWT
var claims = token.Claims;
var jwtPayload = "{";
foreach(Claim c in claims)
{
jwtPayload += '"' + c.Type + "\":\"" + c.Value + "\",";
}
jwtPayload += "}";
txtJwtOut.Text += "\r\nPayload:\r\n" + JToken.Parse(jwtPayload).ToString(Formatting.Indented);
}
I hope that answer your qustions

JWT replay validation based on jti claim rather than on expiration time

In my Asp.net Core based Web API I would like to use jti (JWT ID) claim to prevent replay attacks while working with JWT (JSON Web Tokens).
As suggested I configured JWT Bearer authentication:
services.AddAuthentication(o =>
{
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateTokenReplay = true,
IssuerSigningKeyResolver = (token, securityToken, kid, parameters) =>
{
// Resolving decryption key
},
TokenReplayValidator = (expirationTime, /*string*/ token, validationParameters) =>
{
// I can check expiration time, but there is no way to check jti
},
};
o.SaveToken = true;
});
In replay validator I can access an expiration time, but there is no way to get jti somehow.
I find it a bit confusing. What common might have a replay attack and an expiration time?
Moreover we have another validator:
bool LifetimeValidator(DateTime? notBefore, DateTime? expires,
SecurityToken securityToken,
TokenValidationParameters validationParameters);
Here I can access the SecurityToken data including jti, but I can't believe that this is a right place for jti-based replay attack validation.
So the question is: how could I get SecurityToken data inside TokenReplayValidator?
UPDATE:
After the #orhtej2 comment, I checked the possibility which he suggested. That works indeed:
TokenReplayValidator = (expirationTime, token, validationParameters) =>
{
var handler = o.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();
var securityToken = handler.ReadJwtToken(token);
var jti = securityToken.Id;
// check replay attack
},
Well, it is a solution, but requires additional token parsing (which cannot be good - unnecessary calculations required on the each HTTP call).
I would like to keep the question unanswered until some better solution found.

ASP core login through external (custom) service

I am looking for proper way how to implement authentification and authorization.
If I understand it well - this should be realized through "Identity" - it's offering both of these things I need.
My problem is that i can't use a database. I have to use a service (WCF service where our internal DDLs are connected to our system) which is able only Login (I give it user name and password) and after login i can get list of permissons.
I already saw articles how to have custom UserStore, RoleStore, UserManager and SignInManager.. but I am still confused and I don't know how to do it.
Is this even posible through Identity model? If not how I should do it please?
Thank you for every advice.
There are some articles which I already checked:
Microsoft - custom storage providers
Core indentity without entity framework
Sikorsky blog - custom user manager
In fact the WCF service is your authentication service. No need to implement this twice. A call to the service verifies the credentials and returns everything that should be in the access token.
Basically all you have to do is generate an access token using the information from the WCF service. And configure your app to use the created access token.
The flow can be like this: first make a call to the WCF service in order to verify the login and retrieve the information.
public async Task<IActionResult> LoginAsync([FromBody]UserLogin login)
{
var loginInfo = _wcf.LoginUser(login);
if (loginInfo == null)
return Unauthorized();
return Ok(CreateAccessToken(loginInfo));
}
To create an access token:
public class TokenHelper
{
public const string Issuer = "http://www.mywebsite.com/myapp";
public const string Audience = "http://www.mywebsite.com/myapp";
// This should not be hardcoded!
public const string Secret = "My_super_secret";
public AccessToken CreateAccessToken(LoginInfo loginInfo)
{
// Set expiration time of 5 minutes.
DateTime expires = DateTime.UtcNow.AddMinutes(5);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, loginInfo.UserId),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
// Add custom claims, rolepermissions
if (loginInfo.Permissions != null && loginInfo.Permissions.Any())
loginInfo.Permissions.foreach(p => claims.Add(new Claim("Permission", p)));
if (loginInfo.IsUser)
claims.Add(new Claim(ClaimTypes.Role, "User"));
if (loginInfo.IsAdmin)
claims.Add(new Claim(ClaimTypes.Role, "Admin"));
var token = new JwtSecurityToken(
issuer: Issuer,
audience: Audience,
claims: claims,
expires: expires,
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Secret)),
SecurityAlgorithms.HmacSha256
)
);
return new AccessToken
{
ServerTime = DateTime.UtcNow.ToString("yyyyMMddTHH:mm:ssZ"),
Expires = expires.ToString("yyyyMMddTHH:mm:ssZ"),
Bearer = new JwtSecurityTokenHandler().WriteToken(token)
};
}
}
Where AccessToken is:
public class AccessToken
{
public string ServerTime { get; set; }
public string Expires { get; set; }
public string Bearer { get; set; }
}
And add authentication in your startup:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidIssuer = TokenHelper.Issuer,
ValidAudience = TokenHelper.Audience,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.ASCII.GetBytes(
TokenHelper.Secret))
};
}
);
-- update --
_issuer, _audience and _secret are from some 'external source'. Meaning that all three are fixed string values, but the source (where the value is set) is variable.
For _issuer you usually use the url of the server that issues the token. Like http://www.mywebsite.com/myapp
The _audience is the application that is meant to accept the token. In this case _issuer and _audience are the same, so you can use the same value.
_secret is, well secret and can be any string, like 'my_super_secret'. This is something you want to stay secret. So you don't hardcode it, but get it from a safe location instead.
I've updated above code in a way so you can test it. Please note that secret should not be hardcoded.

How Do I Manually Validate a JWT Asp.Net Core?

There are millions of guides out there, and none of them seem to do what I need. I am creating an Authentication Server, that simply just needs to issue, and validate/reissue tokens. So I can't create a middleware class to "VALIDATE" the cookie or header. I am simply receiving a POST of the string, and I need to validate the token that way, instead of the Authorize middleware that .net core provides.
My Startup Consists of the only Token Issuer Example I could get working.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
var secretKey = "mysupersecret_secretkey!123";
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
var options = new TokenProviderOptions
{
// The signing key must match!
Audience = "AllApplications",
SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
Issuer = "Authentication"
};
app.UseMiddleware<TokenProviderMiddleware>(Microsoft.Extensions.Options.Options.Create(options));
I can use the middleware on creation since I just need to intercept the body for the username and password. The middleware takes in the options from the previous Startup.cs code, checks the Request Path and will Generate the token from the context seen below.
private async Task GenerateToken(HttpContext context)
{
CredentialUser usr = new CredentialUser();
using (var bodyReader = new StreamReader(context.Request.Body))
{
string body = await bodyReader.ReadToEndAsync();
usr = JsonConvert.DeserializeObject<CredentialUser>(body);
}
///get user from Credentials put it in user variable. If null send bad request
var now = DateTime.UtcNow;
// Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
// You can add other claims here, if you want:
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, JsonConvert.SerializeObject(user)),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, now.ToString(), ClaimValueTypes.Integer64)
};
// Create the JWT and write it to a string
var jwt = new JwtSecurityToken(
issuer: _options.Issuer,
audience: _options.Audience,
claims: claims,
notBefore: now,
expires: now.Add(_options.Expiration),
signingCredentials: _options.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
///fill response with jwt
}
This large block of code above will Deserialize the CredentialUser json and then execute a stored procedure that returns the User Object. I will then add three claims, and ship it back.
I am able to successfully generate a jwt, and using an online tool like jwt.io, I put the secret key, and the tool says it is valid, with an object that I could use
{
"sub": " {User_Object_Here} ",
"jti": "96914b3b-74e2-4a68-a248-989f7d126bb1",
"iat": "6/28/2017 4:48:15 PM",
"nbf": 1498668495,
"exp": 1498668795,
"iss": "Authentication",
"aud": "AllApplications"
}
The problem I'm having is understanding how to manually check the claims against the signature. Since this is a server that issues and validates tokens. Setting up the Authorize middleware is not an option, like most guides have. Below I am attempting to Validate the Token.
[Route("api/[controller]")]
public class ValidateController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Validate(string token)
{
var validationParameters = new TokenProviderOptions()
{
Audience = "AllMyApplications",
SigningCredentials = new
SigningCredentials("mysupersecret_secretkey!123",
SecurityAlgorithms.HmacSha256),
Issuer = "Authentication"
};
var decodedJwt = new JwtSecurityTokenHandler().ReadJwtToken(token);
var valid = new JwtSecurityTokenHandler().ValidateToken(token, //The problem is here
/// I need to be able to pass in the .net TokenValidParameters, even though
/// I have a unique jwt that is TokenProviderOptions. I also don't know how to get my user object out of my claims
}
}
I stole borrowed this code mostly from the ASP.Net Core source code: https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs#L45
From that code I created this function:
private string Authenticate(string token) {
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
List<Exception> validationFailures = null;
SecurityToken validatedToken;
var validator = new JwtSecurityTokenHandler();
// These need to match the values used to generate the token
TokenValidationParameters validationParameters = new TokenValidationParameters();
validationParameters.ValidIssuer = "http://localhost:5000";
validationParameters.ValidAudience = "http://localhost:5000";
validationParameters.IssuerSigningKey = key;
validationParameters.ValidateIssuerSigningKey = true;
validationParameters.ValidateAudience = true;
if (validator.CanReadToken(token))
{
ClaimsPrincipal principal;
try
{
// This line throws if invalid
principal = validator.ValidateToken(token, validationParameters, out validatedToken);
// If we got here then the token is valid
if (principal.HasClaim(c => c.Type == ClaimTypes.Email))
{
return principal.Claims.Where(c => c.Type == ClaimTypes.Email).First().Value;
}
}
catch (Exception e)
{
_logger.LogError(null, e);
}
}
return String.Empty;
}
The validationParameters need to match those in your GenerateToken function and then it should validate just fine.

Authenticating a user in a MVC application using JSON Web Tokens

I have a legacy application from which I want to spawn a session in a new asp.net MVC application. I am attempting to pass a JSON Web Token to the MVC application to authenticate the user. I have it working for the most part, but it is requiring some extra code to get the user signed in (using Request.GetOwinContext().ctx.Authentication.SignIn) . It is making me question whether I am going down the correct path.
From what I have read I would think that I should be able to use the ClaimsPrincipal object created by the ValidateToken method to sign the user into the application.
My Issues:
The ClaimsIdentity instance created by ValidateToken sets the Authentication Type to Federated. To sign the user into the MVC application, I need to set the authentication type to Cookies (I think). To do this I am creating a new ClaimsIdentity instance based off the one created by ValidateToken and then passing ApplicationCookie as the authentication type to the constructor. Is it necessary to be doing this and is there a way to change the authentication type on the original ClaimsIdentity instance without creating a new one?
I cannot get the name property to be set automatically by the ValidateToken method. The SignIn method seems to require that to be set. To get around this I set it explicitly by pulling the name claim from the ClaimsIdentity instance created by ValidateToken (ident2.AddClaim(new Claim(ClaimTypes.Name, myIdentity.FindFirstValue("Name")));). Is there a claim I can pass in the payload of the JWT that will be mapped to this property automatically?
Or in general is this the wrong approach to accomplish the authentication?
The claims set of the payload for my JWT looks something like:
{
"iss": "http://oldapp.testing.com",
"aud": "http://newapp.testing.com",
"sub": "99239",
"iat": 1425507035,
"exp": 1425507065,
"name": "First Last",
"role": [
"Admin"
]
And the C# code to process it:
JwtSecurityToken tokenReceived = new JwtSecurityToken(token);
JwtSecurityTokenHandler recipientTokenHandler = new JwtSecurityTokenHandler();
byte[] keyBytes = Encoding.UTF8.GetBytes("someTestSecretKeyForTestingThis");
if (keyBytes.Length < 64 && tokenReceived.SignatureAlgorithm == "HS256")
{
Array.Resize(ref keyBytes, 64);
}
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidIssuer = "http://oldapp.testing.com",
ValidAudience = "http://newapp.testing.com",
IssuerSigningToken = new BinarySecretSecurityToken(keyBytes)
};
try
{
SecurityToken validatedToken;
var principal = recipientTokenHandler.ValidateToken(token, validationParameters, out validatedToken);
// Pull out the ClaimIdentity created by ValidateToken
var myIdentity = principal.Identities.FirstOrDefault();
//
// Copy ClaimIdentity created by the ValidateToken method and change the Authentication
// type from Federated to Cookie
//
// Is there a better way to do this???
//
var ident2 = new ClaimsIdentity(myIdentity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
//
// Make sure the Name claim is set correctly so that the SignIn method will work
//
// Why isn't the Name claim set automatically???
//
ident2.AddClaim(new Claim(ClaimTypes.Name, myIdentity.FindFirstValue("Name")));
// Sign the user in
var ctx = Request.GetOwinContext();
var authManager = ctx.Authentication;
authManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
authManager.SignIn(ident2);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception :" + ex.Message);

Categories