엔티티 프레임 워크를 사용하여 타사 인증을 사용하여 새 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와 관련이 있다고 느끼지만 왜 그런지 모르겠다. ...
잘 모르겠지만 검토해보십시오. http://msdn.microsoft.com/en-us/library/hh291061(v=vs.110).aspx 그리고 http://brockallen.com/2012/07/08/mvc-4-antiforgerytoken-and-claims/ –
@ClarkKent 감사합니다.하지만이 둘은 주로 WIF를 사용하는 이전 구현에 대해 이야기하는 것 같습니다. 그게 내 자신의 ClaimsIdentityFactory를 구현하고 수동으로 거기에 UserManager에서 클레임을로드해야하지만, 그것은 모든 종류 또는 잘못 느낀 것 같습니다. –