2016-12-06 4 views
1

Ich möchte etwas in meinem 'Identity' generierten Cookie speichern. Ich verwende derzeit die Standard-Identity-Einrichtung aus den Google Docs.Token in Cookie mit ASP.NET Core Identity speichern

Startup.cs

services.Configure<IdentityOptions>(options => 
{ 
    // User settings 
    options.User.RequireUniqueEmail = true; 

    // Cookie settings 
    options.Cookies.ApplicationCookie.AuthenticationScheme = "Cookies"; 
    options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromHours(1); 
    options.Cookies.ApplicationCookie.SlidingExpiration = true; 
    options.Cookies.ApplicationCookie.AutomaticAuthenticate = true; 
    options.Cookies.ApplicationCookie.LoginPath = "/Account"; 
    options.Cookies.ApplicationCookie.LogoutPath = "/Account/Logout"; 
}); 

AccountController.cs

var result = await _signInManager.PasswordSignInAsync(user.UserName, model.Password, true, true); 

if (result.Succeeded) 
{ 
    _logger.LogInformation(1, "User logged in."); 

    var tokens = new List<AuthenticationToken> 
    { 
     new AuthenticationToken {Name = "Test", Value = "Test"}, 
    }; 


    var info = await HttpContext.Authentication.GetAuthenticateInfoAsync("Cookies"); 
    info.Properties.StoreTokens(tokens); 

Es scheint dies nicht funktioniert. Weil der Cookie noch nicht erstellt wurde. Die Variable 'Info' ist leer.

Ich konnte es lösen, indem sie mit der 'CookieMiddleware'

Startup.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationScheme = "Cookies", 
    ExpireTimeSpan = TimeSpan.FromHours(1), 
    SlidingExpiration = true, 
    AutomaticAuthenticate = true, 
    LoginPath = "/Account", 
    LogoutPath = "/Account/Logout", 
}); 

Aber als ich brauche

await HttpContext.Authentication.SignInAsync("Cookies", <userPrincipal>); 

In diesem Fall verwenden muss ich mich bauen ein "Benutzerprinzipal". Und ich ziehe es vor, "Identität" für diese Angelegenheit zu nutzen.

So ist es möglich, dies zu kombinieren? Wenn dies nicht der Fall ist, wie erzeuge ich das Claimsprincipal auf einem guten Weg.

Ohne die Notwendigkeit, jeden Anspruch "abzubilden".

List<Claim> userClaims = new List<Claim> 
{ 
    new Claim("UserId", Convert.ToString(user.Id)), 
    new Claim(ClaimTypes.Name, user.UserName), 
    // TODO: Foreach over roles 
}; 

ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(userClaims)); 
await HttpContext.Authentication.SignInAsync("Cookies", principal); 

So etwas wie:

ClaimsPrincipal pricipal = new ClaimsPrincipal(user.Claims); 

Das funktioniert nicht, weil user.Claims vom Typ IdentityUserClaim ist und nicht vom Typ Security.Claims.Claim.

Danke fürs Lesen. Haben ein guter Tag,

Mit freundlichen Grüßen, Brecht

Antwort

2

ich es geschafft, mein Problem zu lösen.

Ich schrieb die gleiche Funktionalität, die im 'signInManager' ist. Aber ich habe meine eigene Authentifizierungseigenschaft hinzugefügt.

var result = await _signInManager.PasswordSignInAsync(user, model.Password, true, true); 
if (result.Succeeded) 
{ 
    await AddTokensToCookie(user, model.Password); 
    return RedirectToLocal(returnUrl); 
} 
if (result.RequiresTwoFactor) 
{ 
    // Ommitted 
} 
if (result.IsLockedOut) 
{ 
    // Ommitted 
} 

Code, der tatsächlich etwas (Token) im Inneren des Cookie speichert:

private async Task AddTokensToCookie(ApplicationUser user, string password) 
{ 
    // Retrieve access_token & refresh_token 
    var disco = await DiscoveryClient.GetAsync(Environment.GetEnvironmentVariable("AUTHORITY_SERVER") ?? "http://localhost:5000"); 

    if (disco.IsError) 
    { 
     _logger.LogError(disco.Error); 
     throw disco.Exception; 
    } 

    var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret"); 
    var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(user.Email, password, "offline_access api1"); 

    var tokens = new List<AuthenticationToken> 
    { 
     new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = tokenResponse.AccessToken}, 
     new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = tokenResponse.RefreshToken} 
    }; 

    var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn); 
    tokens.Add(new AuthenticationToken 
    { 
     Name = "expires_at", 
     Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) 
    }); 

    // Store tokens in cookie 
    var prop = new AuthenticationProperties(); 
    prop.StoreTokens(tokens); 
    prop.IsPersistent = true; // Remember me 

    await _signInManager.SignInAsync(user, prop); 
} 

Die letzten 4 Zeilen Code sind die wichtigsten.

Verwandte Themen