5

Jestem stackoverflow noob, więc proszę idź łatwo, jeśli robię to źle.Wyodrębnij tożsamość rdzenia asp.net i zapisz zewnętrzne tokeny logowania i dodaj roszczenia do lokalnej tożsamości.

Używam core asp.net z domyślnym szablonem tożsamości rdzenia (konta lokalne).

Mam accertained jak dodać roszczeń do głównego użytkownika, gdy się zalogować lokalnie jak tak

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Login(LoginInputModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      // This doesn't count login failures towards account lockout 
      // To enable password failures to trigger account lockout, set lockoutOnFailure: true 

      var user = await _userManager.FindByNameAsync(model.Email); 

      await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value")); 

I zorientowali się, jak dostać się roszczeń zwracane z logowania zewnętrznego, ale nie mogę dowiedzieć się, jak Dodałbym przed ich główny użytkownik zostanie utworzony w funkcji ExternalLoginCallback

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) 
    { 
     if (remoteError != null) 
     { 
      ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}"); 
      return View(nameof(Login)); 
     } 

     var info = await _signInManager.GetExternalLoginInfoAsync(); 
     if (info == null) 
     { 
      return RedirectToAction(nameof(Login)); 
     } 
     else { 
      // extract claims from external token here 
     } 

     // assume add claims to user here before cookie gets created?? 

     // Sign in the user with this external login provider if the user already has a login. 
     var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); 
     if (result.Succeeded) 

jestem przy założeniu, że funkcja _signInManager.ExternalLoginSignInAsync działa podobnie do miejscowego _signInManager.PasswordSignInAsync logowania w tym sensie, że po nazywa się, ciasteczko zostanie utworzone. Ale po prostu nie jestem pewien.

Zasadniczo to, co mam nadzieję osiągnąć, to zrozumienie sposobu dodawania niestandardowych roszczeń do tworzonego pliku cookie, niezależnie od tego, w jaki sposób loguje się użytkownik (lokalny lub zewnętrzny), oraz w jaki sposób zachować te informacje w bazie danych, jeśli jest to wymagane .

Mam zamiar wykonać pewną pracę, jeśli mam login użytkownika, używając google auth, muszę zapisać ten access_token z google, ponieważ chcę połączyć się z API Google później z nim. Dlatego muszę mieć możliwość włączenia tego access_token do głównego użytkownika, który zostanie utworzony, i mam nadzieję, że plik cookie będzie miał na nim roszczenia, które mógłbym wykorzystać również w interfejsie użytkownika.

To może być poza zakresem na to pytanie, ale chciałbym również, aby wygasł token Google, dla niektórych - jak używać tokena odświeżania, aby uzyskać nowy lub zmusić użytkownika do ponownego zalogowania.

Każda pomoc w tej sprawie byłaby bardzo doceniana. Naprawdę bardzo się starałem to zrozumieć, nie publikując tego pytania do stackoverflow. Czytałem wiele artykułów z dużą ilością przydatnych informacji, ale nie dostarczam odpowiedzi na to pytanie. Dziękuję bardzo z góry.

okrzyki

Odpowiedz

4

Podczas korzystania await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value")); że faktycznie uaktualnia aspnetuserclaims tabeli tożsamości użytkownika.

Za każdym razem, gdy się logujesz (używając _signInManager.PasswordSignIn lub _signInManager.ExternalLoginSignInAsync) roszczenia z tej tabeli są odczytywane i dodawane do pliku cookie, który na każde żądanie staje się Zleceniodawcą.

Prawdopodobnie nie chcesz wywoływać metody AddClaimAsync z UserManager przy każdym logowaniu.

dotyczących zewnętrznych dostawców logowania, masz dostęp do roszczeń, gdy dzwonisz (w ExternalCallback i ExternalCallbackConfirmation jeśli używasz szablonów domyślnych) tutaj:

var info = await _signInManager.GetExternalLoginInfoAsync(); 

Roszczenia są info.Principal.Claims.

Token dostępu nie jest domyślnie dołączony.Gdy tak jest, to będzie tutaj (wraz z rodzajem i datą ważności):

var accessToken = info.AuthenticationTokens.Single(f => f.Name == "access_token").Value; 
var tokenType = info.AuthenticationTokens.Single(f => f.Name == "token_type").Value; 
var expiryDate = info.AuthenticationTokens.Single(f => f.Name == "expires_at").Value; 

Aby mieć token dostępu zostać włączone do kolekcji AuthenticationTokens, podczas konfigurowania middleware GoogleAuthentication ustawić flagę SaveTokens true :

 app.UseGoogleAuthentication(new GoogleOptions{ 
      ClientId = "...", 
      ClientSecret = "...", 
      SaveTokens = true 

teraz, jeśli chcesz mieć kontrolę nad tym, które twierdzi iść w ciasteczkach trzeba „przejąć” proces tworzenia kapitału roszczeń.

Jest to zrobione podczas korzystania z _signInManager.PasswordSignIn/ExternalLoginSignInAsync.

Tak więc, na przykład, dla ExternalLoginSignInAsync wymienić:

var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); 

Z:

var user = await this._userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey); 
    var claimsPrincipal = await this._signInManager.CreateUserPrincipalAsync(user); 
    ((ClaimsIdentity)claimsPrincipal.Identity).AddClaim(new Claim("accessToken", info.AuthenticationTokens.Single(t => t.Name == "access_token").Value)); 
    await HttpContext.Authentication.SignInAsync("Identity.Application", claimsPrincipal); 

"Identity.Application" to domyślna nazwa pliku cookie. Można go zmienić w ConfigureServices metody Startup za, na przykład do MainCookie:

 services.Configure<IdentityOptions>(options => { 
      options.Cookies.ApplicationCookie.AuthenticationScheme = "MainCookie"; 
     }); 

Trzeba jeszcze obsłużyć działań w AccountController ExternalCallbackConfirmation. Będzie podobny do powyższego przykładu.