클레임 담당자를 기반으로 ID 사용자를 만드는 방법 [중복]

Nov 24 2020

직장 / 학교 계정 인증과 함께 asp.net mvc를 사용하고 있습니다. 현재 저는 사용자 프로세스에 ID를 구현하려고합니다.

ApplicationUser수업 은 다음과 같습니다 .

public class ApplicationUser: IdentityUser
{
    public ICollection<Semester> Semesters { get; set; }
}

지금까지 정체성은 잘 작동하지만 한 가지 문제가 있습니다. 학교 계정으로 앱에 로그인 하면 컨트롤러 에서 ClaimsPrincipals로 전화 할 수 있습니다 User. 현재 얻으려면 ApplicationUser당신이 사용할 수를 UserManager( await _userManager.GetUserAsync(User)함께 UserClaimsPrincipals)하지만 데이터베이스에 내 학교 계정에 저장되어 있지 않기 때문에, 결과는 null가됩니다. ApplicationUser다음과 같이 새로 만들면

var newUser = new ApplicationUser()
{
    UserName = User.Identity.Name,
    Email = User.Identity.Name
};
await _userManager.CreateAsync(newUser);
await _userManager.AddClaimsAsync(newUser, User.Claims);

이렇게하면 클레임이있는 데이터베이스에 새 사용자를 성공적으로 만들고 저장합니다. 하지만 내가 만든 새 얻을 때 ApplicationUserawait _userManager.GetUserAsync(User)여전히 null이됩니다 결과를. 내 액세스 DbContext하여 모든을 얻으면 ApplicationUsers새로 생성 된 파일 ApplicationUser이 있습니다. 그렇다면 학교 계정 로그인에서 얻은 정보를 ApplicationUser기반으로 어떻게 만들 수 ClaimsPrincipals있습니까?

답변

Ogglas Dec 07 2020 at 19:49

이것에 대한 @poke에 대한 크레딧.

UserManager.GetUserAsync내부적으로는 UserManager.GetUserId사용자 저장소 (즉, 데이터베이스)에서 개체를 쿼리하는 데 사용되는 사용자의 사용자 ID를 검색하는 데 사용합니다.

GetUserId 기본적으로 다음과 같습니다.

public string GetUserId(ClaimsPrincipal principal)
{
    return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}

따라서 이것은의 클레임 값을 반환합니다 Options.ClaimsIdentity.UserIdClaimType. ID를 구성 Options하는 IdentityOptions개체 입니다. 기본 값으로 UserIdClaimTypeIS ClaimTypes.NameIdentifier즉, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier".

따라서 UserManager.GetUserAsync(HttpContext.User)해당 사용자 주체에 UserID클레임 이있는를 사용하려고 하면 사용자 관리자는 단순히 다른 클레임을 찾고 있습니다.

다음 중 하나로 전환하여이 문제를 해결할 수 있습니다 ClaimTypes.NameIdentifier.

new ClaimsIdentity(new[]
{
    new Claim(ClaimTypes.Name, user.UserName),
    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})

또는 UserID클레임 유형 을 사용하도록 ID를 올바르게 구성 합니다.

// in Startup.ConfigureServices
services.AddIdentity(options => {
    options.ClaimIdentity.UserIdClaimType = "UserID";
});

출처:

https://stackoverflow.com/a/51122850/3850405

MattE. Dec 04 2020 at 05:55

외부 공급자의 클레임은 해당 공급자에 따라 다릅니다. 앱의 로컬 ID 저장소에 로그인하는 것이 아니라 사용자가 누구인지 알고 있다고 주장하는 것입니다. 따라서 인증에 사용하려면 먼저 사용자를 상점 (SignInManager)에 로그인해야합니다. 리소스 보호에 신경 쓰지 않고 사용자를 알고 싶다면 내부 저장소에 직접 매핑 할 수 있습니다.

헤더의 클레임은 HttpContext에서 User 개체를 설정하는 인증 공급자를 사용하여 ASPNET '미들웨어'에서 가로 채야합니다. 사용자가 있으면 로컬 사용자 저장소를 학교 계정의 저장소에 매핑 한 다음 결과에서 별도의 호출로 클레임을 가져와야합니다. 일반적으로 이메일은 제목 클레임이며 매핑에 사용할 수 있습니다.

    var userName = User.Identity.Name;
    var user = _userManager.FindByNameAsync(userName);
    var claims = _userManager.GetClaimsAsync(user);