2016-01-22 15 views
6

JWT ile Kimlik ve rol tabanlı haklar oluşturma hakkında bitoftech tutorial boyunca devam ediyorum. Uygulama kullanıcım int PK ile özel bir Kullanıcı tablosu.CreateUserIdenityAsync, özel IdentityUser için "UserId found" özel durumu döndürüyor

Şu anda, GenerateUserIdentityAsync yöntemi bir garip UserId not found hatasını döndürür.

ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); 

ve User varlıktaki uygulama: İşte benim kod

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User, int> manager, string authenticationType) 
{ 
    //error on this line: CreateIdentityAsync throws error 
    var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); 
    return userIdentity; 
} 

Benim UserManager sınıfı şöyle tanımlanır:

public class AppUserManager : UserManager<User, int> 

Tuhaftır ki ben hata ayıklarken, örneğini thisGenerateIdentityAsync, UserId özelliğinde yok, ancak yalnızca id taban var ve acaba bu nerede? e hata mı yapıyor? (doğru gelmiyor)

source code (satır 80) 'a bakıyordum ancak istisnanın nereye atılacağını anlayamıyorum.

atılan kesin istisnadır:

UserId not found. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: 
    System.InvalidOperationException: 
    UserId not found. 

Ve stack trace değil tüm bu yararlı (bana)

KullanıcıNo mevcut olmadığı neden/öğrenebilirim nasıl?


Mod ayrıntıları:

Benim GrantResourceOwnerCredentials():

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); 

    var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); 
    User user = await userManager.FindAsync(context.UserName, context.Password); 

    if (user == null) // this is NOT null 
    { 
     context.SetError("invalid_grant", "The username or password is incorrect"); 
     return; 
    } 

    // this line fails 
    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); 
    var ticket = new AuthenticationTicket(oAuthIdentity, null); 
    context.Validated(ticket); 
} 

Ve öğrendim gibi

public partial class User : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim> 
{ 
    public int UserId { get; set; } 
    public string Fullname { get; set; } 
    public string Address { get; set; } 
    public string ContactNumber { get; set; } 
} 
+0

Doğru sütun adlarına sahipseniz (ad yerine UserId veya tam tersi) aspnet db'nizde doğrulayın. Ayrıca bir olasılık, sütun tipi uyuşmazlığıdır (nvarchar'a karşı tekil tanımlayıcılar (256)). – Batuta

cevap

3

(benim durumumda, sadece User olduğunu) ApplicationUserhata ayıklanırken, sizin durumunuzda Kullanıcının Kimliğini temsil eden bir Id'a sahiptir.

Sen IdentityUser gelen tabanını Id kullanmak ve Id için özel kullanıcı tablosundaki UserId sütunu yeniden adlandırabilir, User sınıftan UserId kaldırmak gerekir.

User sınıfınızda sahip olduğunuz tüm özelliklerin, veritabanında kullanıcı masanızda eşleşen bir sütunun bulunması gerekir. Aksi halde eşleşmeyen özellikler için aynı hatayı alırsınız. Fullname, Address ve ContactNumberAspNetUsers tablodaki sütun adları eşleşen olmalıdır yoksa siz de bu mülkler için aynı hatayı alacak anlamına gelecektir

.

+0

Merhaba, bu değişiklikleri benimkinde yaptım, ama yine de aynı hatayı atıyor; Ben şimdi 'UserId' olduğunu düşündüğüm şey var mı, iç bir istisna yok, sadece yığın iz yok, ama bu ne yazık ki çok fazla yardım değil. Yukarıdaki kodunuz iki kez kullanıcıyı çeker, bu bir sorun değilse işe yaramadı, daha sonra yeniden odaklanabiliyordum, ama yine de aynı istisnayı – LocustHorde

+0

@ LoocHorde atıyor, çizim tahtasına geri döndüm ve sorununuzu yeniden kontrol ettim. Sağladığınız ek bilgileri kullanarak, iç istisna dahil, aynı istisnayı yeniden oluşturabiliyordum. 'UserId '' AspNetUsers 'Tablosunda geçerli bir sütun olması gerekiyor. Bir önceki yorumcu da bunu da gösterdi. – Nkosi

+0

Mükemmel! Yorumunuzdan sonra iki 'UserId 'yanı sıra' Id 'sütunlarının tabloya göre olduğunu fark ettim ve benim tohum yöntemimde sadece' UserId 'öğesini ve' Id 'sıfırını kullanıyordum.Giriş yapmaya çalıştığımda, "UserId" atma yöntemi ne olursa olsun bulunamadı. Sıfırı bir tam sayıya manüel olarak değiştirdiğimde, çalışmaya başladı! Bu yüzden 'Id' kaldırmak zorundayım ve bir şekilde Identity 'yerine UserId' kullanmak için söyle ... – LocustHorde

2

ApplicationUser sınıfınız nasıl görünür? Bu yöntem uygulamanızda nasıl görünür?

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){} 

GrantResourceOwnerCredentials hakkında Taiseer yorumları belirtmektedir:

"Biz, kullanıcı kimliği doğrulanmış kullanıcı için tüm rolleri ve iddialar içerecektir bu kimliği açmış için bir kimlik inşa ediyoruz"

Benzer bir sorunu gidermek için ClaimTypes.NameIdentifier öğesini ClaimsIdentity'ye eklemeliydim. - IdIdentityUser devralınan

ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); 

if (user == null) 
{ 
    context.SetError("invalid_grant", "The user name or password is incorrect."); 
    return; 
} 

var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); 
+0

Merhaba, yukarıdaki kod bloklarını da ekledim; JWT kullanmıyor musunuz? – LocustHorde

+0

"DefaultAuthenticationTypes.ApplicationCookie" ve hala aynı hata ile denedim, sanırım ben JWT en azından şimdilik – LocustHorde

+0

ile çakışıyor, JWT kullanmıyordum. – BBauer42

2

Sen User sınıfta hem UserId ve Id özelliklere sahiptir: İşte benim GrantResourceOwnerCredentials yönteminin önemli bir parçasıdır. Sorun, User için birincil anahtar olacak şekilde UserId yapılandırmanızdır.

Eğer line 97UserManager.GetSecurityStampAsync üzerine, ClaimsIdentityFactory.CreateAsync yöntemde atılır olsun istisna. Gördüğünüz gibi, bir güvenlik damgası almak için user.Id kullanılır. Eğer UserManager.GetSecurityStampAsync içine bakarsak

sizin olsun istisna tam burada atılır olduğunu göreceksiniz:

public virtual async Task<string> GetSecurityStampAsync(TKey userId) 
{ 
    ThrowIfDisposed(); 
    var securityStore = GetSecurityStore(); 
    var user = await FindByIdAsync(userId).WithCurrentCulture(); 
    if (user == null) 
    { 
     throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound, 
      userId)); 
    } 
    return await securityStore.GetSecurityStampAsync(user).WithCurrentCulture(); 
} 

Böylece User sınıftan UserId özelliğini kaldırmak ve bunun yerine ( IdentityUser miras) Id kullanmaya başlayın.

2

Tam olarak aynı sorunla karşılaşıyorum. Bir baş ağrısından sonra gerçek problemi çözebilirim. Kullanıcı sınıfının Id özelliğine ait veri tipini dize olarak değiştirdiğinizde, yapıcıdaki Kimlik özelliğine bir Guid(). ToString() atanır ve aynı değer veritabanına kaydedilir ve Kimlik, kullanıcı ayrıntılarını kullanarak bu bilgileri alır. değer.

Ancak, Id özelliği için veri türünü int olarak değiştirdiyseniz ve bu özellik için yapıcıda bir değer sağlamadıysanız, Kimlik varsayılan int değerini (0) kullanarak Kullanıcı ayrıntılarını almaya çalışır. nedenleri "System.InvalidOperationException: UserId bulunamadı" iletisini atar.

Veritabanındaki değeri command.ExecuteScalar() ile alarak ve değeri user.Id.'ye atayarak bunu çözdüm. Umarım bu, benzer bir problemle karşılaşan birine yardımcı olur.

+0

Hi @vkuttyp, hangi kurucudan bahsediyorsunuz? Teşekkürler. – chemitaxis

+0

Biraz daha fazla ayrıntı paylaşabilir misiniz? Bu kullanıcıyı tam olarak nerede ayarladın? teşekkürler –

+0

Merhaba @chemitaxis, bahsettiğim kurucu IdentityUser sınıfı yapıcısıdır. – vkuttyp

İlgili konular