ASP.NET Identity'de bir talep nasıl güncellenir?


95

MVC5 projem için OWIN kimlik doğrulaması kullanıyorum. Bu benimSignInAsync

 private async Task SignInAsync(ApplicationUser user, bool isPersistent)
        {
            var AccountNo = "101";
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            identity.AddClaim(new Claim(ClaimTypes.UserData, AccountNo));
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent, RedirectUri="Account/Index"}, identity);
        }

Gördüğünüz gibi AccountNo, Talepler listesine ekledim .

Şimdi, bu Talebi başvurumun bir noktasında nasıl güncelleyebilirim? Şimdiye kadar şuna sahibim:

 public string AccountNo
        {

            get
            {
                var CP = ClaimsPrincipal.Current.Identities.First();
                var Account= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData);
                return Account.Value;
            }
            set
            {
                var CP = ClaimsPrincipal.Current.Identities.First();
                var AccountNo= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData).Value;
                CP.RemoveClaim(new Claim(ClaimTypes.UserData,AccountNo));
                CP.AddClaim(new Claim(ClaimTypes.UserData, value));
            }

        }

Talebi kaldırmaya çalıştığımda şu istisnayı alıyorum:

İddia ' http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata : 101' kaldırılamadı. Ya bu Kimliğin bir parçası değildir ya da bu Kimliği içeren Yöneticiye ait bir iddiadır. Örneğin, Sorumlu rollere sahip bir GenericPrincipal oluştururken hak talebinin sahibi olacaktır. Roller, yapıcıda iletilen, ancak gerçekte Kimliğe ait olmayan Kimlik aracılığıyla açığa çıkarılacaktır. RolePrincipal için de benzer bir mantık mevcuttur.

Birisi Talebi nasıl güncelleyeceğimi öğrenmeme yardım edebilir mi?


Kullanıcı Bilgilerini bir Talepte depoluyorsanız ve Talebi güncellemek istiyorsanız, Kullanıcı Bilgileri değiştikten SignInManager.SignInAsyncsonra Talebin değerini yenilemek için : çağrısını yapabilirsiniz . Bu soruya
Hooman Bahreini

Yanıtlar:


125

Belirli bir ClaimsIdentity'ye göre Talep Eklemek / Güncellemek / Okumak için bir Uzantı yöntemi oluşturdum

namespace Foobar.Common.Extensions
{
    public static class Extensions
    {
            public static void AddUpdateClaim(this IPrincipal currentPrincipal, string key, string value)
            {
                var identity = currentPrincipal.Identity as ClaimsIdentity;
                if (identity == null)
                    return;

                // check for existing claim and remove it
                var existingClaim = identity.FindFirst(key);
                if (existingClaim != null)
                    identity.RemoveClaim(existingClaim);

                // add new claim
                identity.AddClaim(new Claim(key, value));
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });
            }

            public static string GetClaimValue(this IPrincipal currentPrincipal, string key)
            {
                var identity = currentPrincipal.Identity as ClaimsIdentity;
                if (identity == null)
                    return null;

                var claim = identity.Claims.FirstOrDefault(c => c.Type == key);
                return claim.Value;
            }
    }
}

ve sonra onu kullanmak

using Foobar.Common.Extensions;

namespace Foobar.Web.Main.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            // add/updating claims
            User.AddUpdateClaim("key1", "value1");
            User.AddUpdateClaim("key2", "value2");
            User.AddUpdateClaim("key3", "value3");
        }

        public ActionResult Details()
        {
            // reading a claim
            var key2 = User.GetClaim("key2");           
        }
    }
}

En sonunda. Buna başka bir çözüm buldum ve işe yarıyor gibiydi ... çoğunlukla. Ama sonuçta her zaman işe yaradığı için bu yönteme geçildi. Teşekkür ederim!
saml

3
Asp.Net One Core için aynı çözüme sahip olan var mı?
Martín

Bu sadece mevcut uygulama için çalışıyor gibi görünüyor. SSO sunucusu tarafından verilen çerezi, diğer uygulamaların da bunlara erişebilmesi için güncellemek istiyorum. Nasıl bir fikriniz var? Teşekkür
Kim

@Whoever Tanımlama bilgisi SSO sunucusu tarafından değiştirilmediğini (ve dolayısıyla güvenilebileceğini) göstermek için imzalandığından, bunu gerçekleştirmenin herhangi bir yolu olup olmadığı için şaşırırdım.
Mog0

2
var iddia = kimlik.Claims.First (c => c.Type == anahtar); return request.Value; var Claims = Identity.Claims.FirstOrDefault (c => c.Type == key) olmalıdır; iade talebi? .Değer;
liuhongbo

57

Yeni bir tane oluşturabilir ClaimsIdentityve bununla talepleri güncelleyebilirsiniz.

set {
    // get context of the authentication manager
    var authenticationManager = HttpContext.GetOwinContext().Authentication;

    // create a new identity from the old one
    var identity = new ClaimsIdentity(User.Identity);

    // update claim value
    identity.RemoveClaim(identity.FindFirst("AccountNo"));
    identity.AddClaim(new Claim("AccountNo", value));

    // tell the authentication manager to use this new identity
    authenticationManager.AuthenticationResponseGrant = 
        new AuthenticationResponseGrant(
            new ClaimsPrincipal(identity),
            new AuthenticationProperties { IsPersistent = true }
        );
}

4
Talebi güncelleyebilirsiniz ancak yine de kullanıcının oturumunu kapatıp güncellenmiş kimlikle giriş yapmanız gerekir.
user3210546

3
hayır, kullanıcının oturumunu kapatmaz, sadece kullanıcının çerezini güncelliyoruz
Irshu

5
Bunun yalnızca kimliği güncellediğini unutmayın. Bu talepleri saklamak ve talep üzerine otomatik olarak yüklemek istiyorsanız, kullanıcı yöneticisinin de bunları kaldırması ve güncellemesine ihtiyacınız vardır. Biraz zaman aldı! :(
Dennis van der Stelt

3
Ya hiç tanımlama bilgim yoksa ve yalnızca accessToken kullanıyorsam? Benim durumumda talepler bir sonraki talepte değişiklik öncesi ile aynıdır. Sahip olduğum iddiaları güncellemenin tek yolu, kullanıcıyı kapatıp tekrar giriş
yapmasını istemektir

1
Bu sadece mevcut uygulama için çalışıyor gibi görünüyor. SSO sunucusu tarafından verilen çerezi, diğer uygulamaların da bunlara erişebilmesi için güncellemek istiyorum. Nasıl bir fikriniz var? Teşekkür
Kim

18

Kimlik tanımlama bilgisindeki değişikliği yansıtmak (ve isteğe bağlı olarak db tablosu AspNetUserClaims'tan talepleri kaldırmak için) Identity'nin UserManager ve SigninManager'ı kullanan başka bir (zaman uyumsuz) yaklaşım:

// Get User and a claims-based identity
ApplicationUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
var Identity = new ClaimsIdentity(User.Identity);

// Remove existing claim and replace with a new value
await UserManager.RemoveClaimAsync(user.Id, Identity.FindFirst("AccountNo"));
await UserManager.AddClaimAsync(user.Id, new Claim("AccountNo", value));

// Re-Signin User to reflect the change in the Identity cookie
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

// [optional] remove claims from claims table dbo.AspNetUserClaims, if not needed
var userClaims = UserManager.GetClaims(user.Id);
if (userClaims.Any())
{
  foreach (var item in userClaims)
  {
    UserManager.RemoveClaim(user.Id, item);
  }
}

Buradaki ipucu, benim için, Talepleri oluşturduktan SignInAsync() sonra yapmaktı .
H köpek

DB'den iddiaları kaldırmayla ilgili ipucu için teşekkürler. Kendimden sonra temizlemem gerektiğini anlamamı sağladı.
Uber Schnoz

13

.Net core 2.1 ile en son Asp.Net Kimliğini kullanarak, aşağıdaki mantıkla kullanıcı taleplerini güncelleyebiliyorum.

  1. Bir kullanıcıyı UserClaimsPrincipalFactoryher SignInManagerşarkı söylediğinde talepler yaratılacak şekilde kaydedin.

    services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, UserClaimService>();
    
  2. UserClaimsPrincipalFactory<TUser, TRole>Aşağıdaki gibi bir özel uygulama

    public class UserClaimService : UserClaimsPrincipalFactory<ApplicationUser, ApplicationRole>
    {
        private readonly ApplicationDbContext _dbContext;
    
        public UserClaimService(ApplicationDbContext dbContext, UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
        {
            _dbContext = dbContext;
        }
    
        public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
        {
            var principal = await base.CreateAsync(user);
    
            // Get user claims from DB using dbContext
    
            // Add claims
            ((ClaimsIdentity)principal.Identity).AddClaim(new Claim("claimType", "some important claim value"));
    
            return principal;
        }
    }
    
  3. Uygulamanızda daha sonra DB'de bir şeyi değiştirdiğinizde ve bunu kimliği doğrulanmış ve oturum açmış kullanıcınıza yansıtmak istediğinizde, aşağıdaki satırlar bunu başarır:

    var user = await _userManager.GetUserAsync(User);
    await _signInManager.RefreshSignInAsync(user);
    

Bu, kullanıcının tekrar oturum açmaya gerek kalmadan güncel bilgileri görebilmesini sağlar. Bunu, sonucu kontrolöre geri göndermeden hemen önce koydum, böylece işlem bittiğinde her şey güvenli bir şekilde yenilenir.

Mevcut talepleri düzenlemek ve güvenli çerez vb. İçin yarış koşulları oluşturmak yerine, kullanıcıyı sessizce oturum açıp durumu yenilemeniz yeterlidir :)


Teşekkürler, aynı sorunla karşılaştık ve bu çözüm, imzalı bir kullanıcının taleplerini güncellemek için daha iyi çalışıyor.
ameya

Teşekkürler! net çekirdek 3.1'de de aynı sorunla karşılaştı
Kevin Tran

7

Ben de bu istisnayı anladım ve her şeyi böyle düzelttim

var identity = User.Identity as ClaimsIdentity;
var newIdentity = new ClaimsIdentity(identity.AuthenticationType, identity.NameClaimType, identity.RoleClaimType);
newIdentity.AddClaims(identity.Claims.Where(c => false == (c.Type == claim.Type && c.Value == claim.Value)));
// the claim has been removed, you can add it with a new value now if desired
AuthenticationManager.SignOut(identity.AuthenticationType);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, newIdentity);

4

Eklemelerimle buradan bazı cevapları yeniden kullanılabilir ClaimsManager sınıfına derledim .

Hak talepleri devam etti, kullanıcı çerezi güncellendi, oturum açma yenilendi.

Önceden özelleştirmediyseniz ApplicationUser'ın IdentityUser ile değiştirilebileceğini lütfen unutmayın. Ayrıca benim durumumda Geliştirme ortamında biraz farklı bir mantığa sahip olması gerekiyor, bu nedenle IWebHostEnvironment bağımlılığını kaldırmak isteyebilirsiniz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using YourMvcCoreProject.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Hosting;

namespace YourMvcCoreProject.Identity
{
    public class ClaimsManager
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly IWebHostEnvironment _env;
        private readonly ClaimsPrincipalAccessor _currentPrincipalAccessor;

        public ClaimsManager(
            ClaimsPrincipalAccessor currentPrincipalAccessor,
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            IWebHostEnvironment env)
        {
            _currentPrincipalAccessor = currentPrincipalAccessor;
            _userManager = userManager;
            _signInManager = signInManager;
            _env = env;
        }

        /// <param name="refreshSignin">Sometimes (e.g. when adding multiple claims at once) it is desirable to refresh cookie only once, for the last one </param>
        public async Task AddUpdateClaim(string claimType, string claimValue, bool refreshSignin = true)
        {
            await AddClaim(
                _currentPrincipalAccessor.ClaimsPrincipal,
                claimType,
                claimValue, 
                async user =>
                {
                    await RemoveClaim(_currentPrincipalAccessor.ClaimsPrincipal, user, claimType);
                },
                refreshSignin);
        }

        public async Task AddClaim(string claimType, string claimValue, bool refreshSignin = true)
        {
            await AddClaim(_currentPrincipalAccessor.ClaimsPrincipal, claimType, claimValue, refreshSignin);
        }

        /// <summary>
        /// At certain stages of user auth there is no user yet in context but there is one to work with in client code (e.g. calling from ClaimsTransformer)
        /// that's why we have principal as param
        /// </summary>
        public async Task AddClaim(ClaimsPrincipal principal, string claimType, string claimValue, bool refreshSignin = true)
        {
            await AddClaim(
                principal,
                claimType,
                claimValue, 
                async user =>
                {
                    // allow reassignment in dev
                    if (_env.IsDevelopment()) 
                        await RemoveClaim(principal, user, claimType);

                    if (GetClaim(principal, claimType) != null)
                        throw new ClaimCantBeReassignedException(claimType);                
                },
                refreshSignin);
        }

        public async Task RemoveClaims(IEnumerable<string> claimTypes, bool refreshSignin = true)
        {
            await RemoveClaims(_currentPrincipalAccessor.ClaimsPrincipal, claimTypes, refreshSignin);
        }

        public async Task RemoveClaims(ClaimsPrincipal principal, IEnumerable<string> claimTypes, bool refreshSignin = true)
        {
            AssertAuthenticated(principal);
            foreach (var claimType in claimTypes)
            {
                await RemoveClaim(principal, claimType);
            }
            // reflect the change in the Identity cookie
            if (refreshSignin)
                await _signInManager.RefreshSignInAsync(await _userManager.GetUserAsync(principal));
        }

        public async Task RemoveClaim(string claimType, bool refreshSignin = true)
        {
            await RemoveClaim(_currentPrincipalAccessor.ClaimsPrincipal, claimType, refreshSignin);
        }

        public async Task RemoveClaim(ClaimsPrincipal principal, string claimType, bool refreshSignin = true)
        {
            AssertAuthenticated(principal);
            var user = await _userManager.GetUserAsync(principal);
            await RemoveClaim(principal, user, claimType);
            // reflect the change in the Identity cookie
            if (refreshSignin)
                await _signInManager.RefreshSignInAsync(user);
        }

        private async Task AddClaim(ClaimsPrincipal principal, string claimType, string claimValue, Func<ApplicationUser, Task> processExistingClaims, bool refreshSignin)
        {
            AssertAuthenticated(principal);
            var user = await _userManager.GetUserAsync(principal);
            await processExistingClaims(user);
            var claim = new Claim(claimType, claimValue);
            ClaimsIdentity(principal).AddClaim(claim);
            await _userManager.AddClaimAsync(user, claim);
            // reflect the change in the Identity cookie
            if (refreshSignin)
                await _signInManager.RefreshSignInAsync(user);
        }

        /// <summary>
        /// Due to bugs or as result of debug it can be more than one identity of the same type.
        /// The method removes all the claims of a given type.
        /// </summary>
        private async Task RemoveClaim(ClaimsPrincipal principal, ApplicationUser user, string claimType)
        {
            AssertAuthenticated(principal);
            var identity = ClaimsIdentity(principal);
            var claims = identity.FindAll(claimType).ToArray();
            if (claims.Length > 0)
            {
                await _userManager.RemoveClaimsAsync(user, claims);
                foreach (var c in claims)
                {
                    identity.RemoveClaim(c);
                }
            }
        }

        private static Claim GetClaim(ClaimsPrincipal principal, string claimType)
        {
            return ClaimsIdentity(principal).FindFirst(claimType);    
        }    

        /// <summary>
        /// This kind of bugs has to be found during testing phase
        /// </summary>
        private static void AssertAuthenticated(ClaimsPrincipal principal)
        {
            if (!principal.Identity.IsAuthenticated)
                throw new InvalidOperationException("User should be authenticated in order to update claims");
        }

        private static ClaimsIdentity ClaimsIdentity(ClaimsPrincipal principal)
        {
            return (ClaimsIdentity) principal.Identity;
        }
    }


    public class ClaimCantBeReassignedException : Exception
    {
        public ClaimCantBeReassignedException(string claimType) : base($"{claimType} can not be reassigned")
        {
        }
    }

public class ClaimsPrincipalAccessor
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ClaimsPrincipalAccessor(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public ClaimsPrincipal ClaimsPrincipal => _httpContextAccessor.HttpContext.User;
}

// to register dependency put this into your Startup.cs and inject ClaimsManager into Controller constructor (or other class) the in same way as you do for other dependencies    
public class Startup
{
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<ClaimsPrincipalAccessor>();
        services.AddTransient<ClaimsManager>();
    }
}

}


2

MVC5 kullandığımda ve talebi buraya eklediğimde.

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(PATAUserManager manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim(ClaimTypes.Role, this.Role));

        return userIdentity;
    }

SignInAsync işlevinde iddia sonucunu kontrol ettiğimde, yine de rol değeri kullanımını alamıyorum. Fakat...

bu istek bittikten sonra, başka bir eylemdeki Rolüne erişebilirim (başka istek).

 var userWithClaims = (ClaimsPrincipal)User;
        Claim CRole = userWithClaims.Claims.First(c => c.Type == ClaimTypes.Role);

bu yüzden, IEnumerable'ın sürecin arkasında güncellendiğine neden olabileceğini düşünüyorum.


1

Bir CookieAuthenticationEventssınıf uygulayıp geçersiz kılarak mevcut kullanıcı için talepleri güncelleyebilirsiniz ValidatePrincipal. Orada eski talebi kaldırabilir, yenisini ekleyebilir ve ardından ile anaparayı değiştirebilirsiniz CookieValidatePrincipalContext.ReplacePrincipal. Bu, veritabanında saklanan herhangi bir talebi etkilemez. Bu, ASP.NET Core Identity 2.2 kullanıyor.

public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
{
    string newAccountNo = "102";

    public override Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        // first remove the old claim
        var claim = context.Principal.FindFirst(ClaimTypes.UserData);
        if (claim != null)
        {
            ((ClaimsIdentity)context.Principal.Identity).RemoveClaim(claim);
        }

        // add the new claim
        ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim(ClaimTypes.UserData, newAccountNo));

        // replace the claims
        context.ReplacePrincipal(context.Principal);
        context.ShouldRenew = true;

        return Task.CompletedTask;
    }
}

Etkinlik sınıfını şuradan kaydetmeniz gerekir Startup.cs:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddScoped<MyCookieAuthenticationEvents>();

    services.ConfigureApplicationCookie(o =>
    {
        o.EventsType = typeof(MyCookieAuthenticationEvents);
    });
}

Yeni AccountNodeğere erişmek için olaylar sınıfına hizmetler enjekte edebilirsiniz, ancak bu sayfadaki uyarıya göre çok pahalı bir şey yapmaktan kaçınmalısınız:

Uyarı

Burada açıklanan yaklaşım, her talepte tetiklenir. Her istekte tüm kullanıcılar için kimlik doğrulama tanımlama bilgilerinin doğrulanması, uygulama için büyük bir performans düşüşüne neden olabilir.


teşekkürler, bu benim için asp.net core 3.1'de harika çalıştı!
darkezm 0

0

Talep detaylarını veritabanından kaldırmak için aşağıdaki kodu kullanabiliriz. Ayrıca, çerez değerlerini güncellemek için tekrar oturum açmamız gerekiyor

 // create a new identity 
            var identity = new ClaimsIdentity(User.Identity);

            // Remove the existing claim value of current user from database
            if(identity.FindFirst("NameOfUser")!=null)
                await UserManager.RemoveClaimAsync(applicationUser.Id, identity.FindFirst("NameOfUser"));

            // Update customized claim 
            await UserManager.AddClaimAsync(applicationUser.Id, new Claim("NameOfUser", applicationUser.Name));

            // the claim has been updates, We need to change the cookie value for getting the updated claim
            AuthenticationManager.SignOut(identity.AuthenticationType);
            await SignInManager.SignInAsync(Userprofile, isPersistent: false, rememberBrowser: false);

            return RedirectToAction("Index", "Home");

0

Çoklu Çerezler, Çoklu İddialar

public class ClaimsCookie
    {
        private readonly ClaimsPrincipal _user;
        private readonly HttpContext _httpContext;
        public ClaimsCookie(ClaimsPrincipal user, HttpContext httpContext = null)
        {
            _user = user;
            _httpContext = httpContext;
        }

        public string GetValue(CookieName cookieName, KeyName keyName)
        {
            var principal = _user as ClaimsPrincipal;
            var cp = principal.Identities.First(i => i.AuthenticationType == ((CookieName)cookieName).ToString());
            return cp.FindFirst(((KeyName)keyName).ToString()).Value;
        }
        public async void SetValue(CookieName cookieName, KeyName[] keyName, string[] value)
        {
            if (keyName.Length != value.Length)
            {
                return;
            }
            var principal = _user as ClaimsPrincipal;
            var cp = principal.Identities.First(i => i.AuthenticationType == ((CookieName)cookieName).ToString());
            for (int i = 0; i < keyName.Length; i++)
            {
                if (cp.FindFirst(((KeyName)keyName[i]).ToString()) != null)
                {
                    cp.RemoveClaim(cp.FindFirst(((KeyName)keyName[i]).ToString()));
                    cp.AddClaim(new Claim(((KeyName)keyName[i]).ToString(), value[i]));
                }

            }
            await _httpContext.SignOutAsync(CookieName.UserProfilCookie.ToString());
            await _httpContext.SignInAsync(CookieName.UserProfilCookie.ToString(), new ClaimsPrincipal(cp),
                new AuthenticationProperties
                {
                    IsPersistent = bool.Parse(cp.FindFirst(KeyName.IsPersistent.ToString()).Value),
                    AllowRefresh = true
                });
        }
        public enum CookieName
        {
            CompanyUserProfilCookie = 0, UserProfilCookie = 1, AdminPanelCookie = 2
        }
        public enum KeyName
        {
            Id, Name, Surname, Image, IsPersistent
        }
    }

0
    if (HttpContext.User.Identity is ClaimsIdentity identity)
        {
            identity.RemoveClaim(identity.FindFirst("userId"));
            identity.AddClaim(new Claim("userId", userInfo?.id.ToString()));
            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(HttpContext.User.Identity));
        }

7
Genellikle birkaç satırlık anonim kod göndermek yerine bir çözümü açıklamak daha iyidir. Nasıl iyi bir cevap yazabilirim ve ayrıca tamamen kod tabanlı cevapları açıklama
Anh Pham

0

Bir .net çekirdek 2.2 uygulaması kullanıyorum ve şu çözümü kullandım: statup.cs

public void ConfigureServices(IServiceCollection services)
        {
        ...
           services.AddIdentity<IdentityUser, IdentityRole>(options =>
               {
                  ...
               })
               .AddEntityFrameworkStores<AdminDbContext>()
               .AddDefaultTokenProviders()
               .AddSignInManager();

kullanım

  private readonly SignInManager<IdentityUser> _signInManager;


        public YourController(
                                    ...,
SignInManager<IdentityUser> signInManager)
        {
           ...
            _signInManager = signInManager;
        }

 public async Task<IActionResult> YourMethod() // <-NOTE IT IS ASYNC
        {
                var user = _userManager.FindByNameAsync(User.Identity.Name).Result;
                var claimToUse = ClaimsHelpers.CreateClaim(ClaimTypes.ActiveCompany, JsonConvert.SerializeObject(cc));
                var claimToRemove = _userManager.GetClaimsAsync(user).Result
                    .FirstOrDefault(x => x.Type == ClaimTypes.ActiveCompany.ToString());
                if (claimToRemove != null)
                {
                    var result = _userManager.ReplaceClaimAsync(user, claimToRemove, claimToUse).Result;
                    await _signInManager.RefreshSignInAsync(user); //<--- THIS
                }
                else ...
              

-1

Uzantı yöntemi benim için harika çalıştı, bir istisna dışında, kullanıcı orada oturum açarsa eski talep kümeleri hala mevcuttu, bu nedenle kullanıcı yöneticisini her şeyden geçirirken olduğu gibi küçük bir değişiklik harika çalışıyor ve oturumu kapatmanıza ve oturum açmanıza gerek yok. İtibarım zedelendiği için doğrudan cevap veremiyorum :(

public static class ClaimExtensions
{
    public static void AddUpdateClaim(this IPrincipal currentPrincipal,    string key, string value, ApplicationUserManager userManager)
    {
        var identity = currentPrincipal.Identity as ClaimsIdentity;
        if (identity == null)
            return;

        // check for existing claim and remove it
        var existingClaim = identity.FindFirst(key);
        if (existingClaim != null)
        {
            RemoveClaim(currentPrincipal, key, userManager);
        }

        // add new claim
        var claim = new Claim(key, value);
        identity.AddClaim(claim);
        var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
        authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });
        //Persist to store
        userManager.AddClaim(identity.GetUserId(),claim);

    }

    public static void RemoveClaim(this IPrincipal currentPrincipal, string key, ApplicationUserManager userManager)
    {
        var identity = currentPrincipal.Identity as ClaimsIdentity;
        if (identity == null)
            return ;

        // check for existing claim and remove it
        var existingClaims = identity.FindAll(key);
        existingClaims.ForEach(c=> identity.RemoveClaim(c));

        //remove old claims from store
        var user = userManager.FindById(identity.GetUserId());
        var claims =  userManager.GetClaims(user.Id);
        claims.Where(x => x.Type == key).ToList().ForEach(c => userManager.RemoveClaim(user.Id, c));

    }

    public static string GetClaimValue(this IPrincipal currentPrincipal, string key)
    {
        var identity = currentPrincipal.Identity as ClaimsIdentity;
        if (identity == null)
            return null;

        var claim = identity.Claims.First(c => c.Type == key);
        return claim.Value;
    }

    public static string GetAllClaims(this IPrincipal currentPrincipal, ApplicationUserManager userManager)
    {
        var identity = currentPrincipal.Identity as ClaimsIdentity;
        if (identity == null)
            return null;

        var claims = userManager.GetClaims(identity.GetUserId());
        var userClaims = new StringBuilder();
        claims.ForEach(c => userClaims.AppendLine($"<li>{c.Type}, {c.Value}</li>"));
        return userClaims.ToString();
    }


}

-2

Hadi bakalım:

            var user = User as ClaimsPrincipal;
            var identity = user.Identity as ClaimsIdentity;
            var claim = (from c in user.Claims
                         where c.Type == ClaimTypes.UserData
                         select c).Single();
            identity.RemoveClaim(claim);

buradan alınır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.