1

엔티티 프레임 워크를 사용하여 타사 인증을 사용하여 새 ID 프레임 워크를 사용하는 ASP MVC 5 사이트를 보유하고 있습니다. 로그인 한 사용자가 있고 기본 ClaimsIdentityFactory에서 제공하는 것으로 보이는 표준 이름 이름 식별자 및 인증 공급자 인 3 개의 클레임이 있습니다.ASP.NET ID가 클레임을로드하지 않습니다.

userManager.AddClaim(userId, new Claim(claimType,claimValue)); 

나는 AspNetUserClaims 테이블의 DB에 보면 그때 난 내 새로운 주장에 대한 행을 참조하십시오 사용자가 어떤 작업을 수행 할 때

나는 다음이를 사용하여에 대한 청구를 추가 할 수 있습니다. 큰.

그러나 내 사용자가 다른 페이지를 방문하면이 새로운 소유권을 확인하지만 결코 찾지 못합니다.

내 초기 문제는 로그인 한 사용자가 새로운 클레임을 포함하도록 쿠키를 업데이트하지 않았기 때문에 프레임 워크에 다시 로그인했을 때 클레임을 읽고 새로운 클레임을 만들 것이라고 생각했습니다. 사용자가 쿠키에 저장됩니다. 하지만 내 사용자가 다시 로그인 할 때도 소유권 주장이 없기 때문에 나는 뭔가를 놓치고 있어야합니다.

이 라인은 ExternalLoginCallback에서 호출 할 때 내가 DB 활동을 기록하는 경우 사실

:

// Sign in the user with this external login provider if the user already has a login 
ApplicationUser user = await UserManager.FindAsync(loginInfo.Login); 

은 내가 무엇을 얻을 것이 이것이다 : 대한 데이터베이스를 조회하려고 아무것도 포함하지

iisexpress.exe' (CLR v4.0.30319: /LM/W3SVC/2/ROOT-2-130416316906840516): Loaded 

'EntityFrameworkDynamicProxies-Microsoft.AspNet.Identity.EntityFramework'. 
SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name] 
    FROM [dbo].[AspNetRoles] AS [Extent1] 
    WHERE (((UPPER([Extent1].[Name])) = (UPPER(@p__linq__0))) AND (NOT ((UPPER([Extent1].[Name]) IS NULL) OR (UPPER(@p__linq__0) IS NULL)))) OR ((UPPER([Extent1].[Name]) IS NULL) AND (UPPER(@p__linq__0) IS NULL)) 


-- p__linq__0: 'TeamManagement' (Type = String, Size = -1) 

-- Executing at 10/04/2014 20:28:29 +01:00 

-- Completed in 2 ms with result: GlimpseDbDataReader 



'iisexpress.exe' (CLR v4.0.30319: /LM/W3SVC/2/ROOT-2-130416316906840516): Loaded 'EntityFrameworkDynamicProxies-Haccapp.Model'. 
SELECT 
    [Extent1].[Discriminator] AS [Discriminator], 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserName] AS [UserName], 
    [Extent1].[PasswordHash] AS [PasswordHash], 
    [Extent1].[SecurityStamp] AS [SecurityStamp], 
    [Extent1].[PreferredEmailAddress] AS [PreferredEmailAddress] 
    FROM [dbo].[AspNetUsers] AS [Extent1] 
    WHERE ([Extent1].[Discriminator] IN (N'ApplicationUser',N'IdentityUser')) AND ([Extent1].[Id] = @p0) 


-- p0: 'SiteOwner' (Type = String, Size = -1) 

-- Executing asynchronously at 10/04/2014 20:28:29 +01:00 

GlimpseDbCommand.TimerStrategy is null 
-- Completed in 6 ms with result: GlimpseDbDataReader 



SELECT 
    [Limit1].[Discriminator] AS [Discriminator], 
    [Limit1].[Id] AS [Id], 
    [Limit1].[UserName] AS [UserName], 
    [Limit1].[PasswordHash] AS [PasswordHash], 
    [Limit1].[SecurityStamp] AS [SecurityStamp], 
    [Limit1].[PreferredEmailAddress] AS [PreferredEmailAddress] 
    FROM (SELECT TOP (1) 
     [Extent2].[Id] AS [Id], 
     [Extent2].[UserName] AS [UserName], 
     [Extent2].[PasswordHash] AS [PasswordHash], 
     [Extent2].[SecurityStamp] AS [SecurityStamp], 
     [Extent2].[PreferredEmailAddress] AS [PreferredEmailAddress], 
     [Extent2].[Discriminator] AS [Discriminator] 
     FROM [dbo].[AspNetUserLogins] AS [Extent1] 
     LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent2] ON ([Extent2].[Discriminator] IN (N'ApplicationUser',N'IdentityUser')) AND ([Extent1].[UserId] = [Extent2].[Id]) 
     WHERE ([Extent1].[LoginProvider] = @p__linq__0) AND (@p__linq__0 IS NOT NULL) AND ([Extent1].[ProviderKey] = @p__linq__1) AND (@p__linq__1 IS NOT NULL) 
    ) AS [Limit1] 


-- p__linq__0: 'Google' (Type = String, Size = -1) 

-- p__linq__1: 'https://www.google.com/accounts/o8/id?id=some_account_id' (Type = String, Size = -1) 

-- Executing asynchronously at 10/04/2014 20:28:29 +01:00 

클레임은 전혀없고 실제로 반환 된 사용자에게는 0 개의 클레임이 있습니다.

ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, defaultAuthenticationTypes.ApplicationCookie); 
AuthenticationManager.SignIn(new AuthenticationProperties {IsPersistent = isPersistent}, identity); 

및 신원은 3 주장이 있습니다

다음 코드는이 일을 계속한다.

사용자로드시 클레임을 데이터베이스에서로드하려면 어떻게해야합니까? 그리고 일단 내가 한 후에는 사이트를 사용하는 동안 내 사용자가 새로 제기 한 모든 클레임이 사용자 쿠키에서 업데이트되도록하려면 어떻게해야합니까?

나는 근본적인 뭔가를 놓치고있는 것처럼 느껴집니다.

편집은 그래서 좀 더이 연주하고 내 자신의 ClaimsIdentityFactory과 같이 구현 만난다 :

public class FullyLoadingClaimsIdentityFactory : ClaimsIdentityFactory<ApplicationUser> 
{ 
    private readonly ApplicationDb db; 

    public FullyLoadingClaimsIdentityFactory(ApplicationDb db) 
    { 
     this.db = db; 
    } 

    public override async Task<ClaimsIdentity> CreateAsync(UserManager<ApplicationUser> manager, ApplicationUser user, string authenticationType) 
    { 
     var currentClaims = db.UserClaims.Where(x => x.User.Id == user.Id).ToList(); 
     var claimsIdentity = await base.CreateAsync(manager, user, authenticationType); 
     claimsIdentity.AddClaims(currentClaims.Select(c=>new Claim(c.ClaimType,c.ClaimValue))); 
     return claimsIdentity; 
    } 
} 

이 명시 적으로 이제 사용자 요구를로드하기 위해 데이터베이스를 쿼리합니다.

public IDbSet<IdentityUserClaim> UserClaims { get; set; } 

나는 내 currentClaims 볼 때 지금은 제대로 테이블 기계가있는 주장을 포함 않습니다 그래서 내가 노출 될 수있는 프레임 워크는 오브젝트를 IdentityUserClaim IdentityDbContext에서 파생 내 클래스에 속성을 추가했다. 만세! 그때 호출 할 때를 제외하고

: 그것은 또한 이전에로드하지 않을 것이라고, 내 주장을로드

var claimsIdentity = await base.CreateAsync(manager, user, authenticationType); 

.사실

나는이로 변경하는 경우 :

var claimsIdentity = await base.CreateAsync(manager, user, authenticationType); 
Trace.WriteLine(claimsIdentity.Claims.Count()); <-- traces 3 
var currentClaims = db.UserClaims.Where(x => x.User.Id == user.Id).ToList(); 
claimsIdentity = await base.CreateAsync(manager, user, authenticationType); 
Trace.WriteLine(claimsIdentity.Claims.Count()); <-- traces 6! 

그때는 DB의 주장을 (이 중 3가) 내가 처음 claimsIdentity하지만 내가 만든 두 번째 시간을 만들 때로드하지 않습니다 내가 DB에 수동으로 쿼리 한 후에 그 신원이 그곳에 있다는 주장입니다.

왜 그럴 수 있습니까? 나는 지금 EF와 관련이 있다고 느끼지만 왜 그런지 모르겠다. ...

+0

잘 모르겠지만 검토해보십시오. http://msdn.microsoft.com/en-us/library/hh291061(v=vs.110).aspx 그리고 http://brockallen.com/2012/07/08/mvc-4-antiforgerytoken-and-claims/ –

+0

@ClarkKent 감사합니다.하지만이 둘은 주로 WIF를 사용하는 이전 구현에 대해 이야기하는 것 같습니다. 그게 내 자신의 ClaimsIdentityFactory를 구현하고 수동으로 거기에 UserManager에서 클레임을로드해야하지만, 그것은 모든 종류 또는 잘못 느낀 것 같습니다. –

답변

2

네, 이것은 v2.0으로 업그레이드 할 때 수정해야하는 버그입니다. 기본적으로 LazyLoading이 활성화되어 있는지 확인하고 싶다면 더 많은 정보를 참조하십시오. here

+0

감사합니다. 내 인생의 3 시간 나는 돌아 오지 않을 것이다. 적어도 지금은 3 :-)입니다. –