C# 如何基于索赔原则创建身份用户
我正在使用asp.net mvc进行工作/学校帐户身份验证。目前,我正在尝试将标识实现到用户进程中 这是我的C# 如何基于索赔原则创建身份用户,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,我正在使用asp.net mvc进行工作/学校帐户身份验证。目前,我正在尝试将标识实现到用户进程中 这是我的ApplicationUser课程: 公共类应用程序用户:IdentityUser { 公共ICollection学期{get;set;} } 到目前为止,身份识别工作正常,只有一个问题。当我使用我的学校帐户登录应用程序时,我可以在控制器中以User的身份调用ClaimsPrincipals。要获取当前的应用程序用户,您可以使用用户管理器(await\u UserManager.GetU
ApplicationUser
课程:
公共类应用程序用户:IdentityUser
{
公共ICollection学期{get;set;}
}
到目前为止,身份识别工作正常,只有一个问题。当我使用我的学校帐户登录应用程序时,我可以在控制器中以User
的身份调用ClaimsPrincipals
。要获取当前的应用程序用户
,您可以使用用户管理器
(await\u UserManager.GetUserAsync(User)
,其中User
是ClaimsPrincipals
),但由于我没有在数据库中存储我的学校帐户,因此结果将为空。如果我创建一个新的应用程序用户
,如下所示
var newUser=newapplicationuser()
{
用户名=User.Identity.Name,
电子邮件=User.Identity.Name
};
wait\u userManager.CreateAsync(newUser);
wait_userManager.AddClaimsAsync(newUser,User.Claims);
这将成功地创建新用户并将其保存到包含声明的数据库中。但是,当我尝试使用
await\u userManager.GetUserAsync(User)
获取新创建的ApplicationUser
时,结果仍然为空。如果访问我的DbContext
并获取所有ApplicationUser
,则新创建的ApplicationUser
就在那里。那么,如何根据我从学校帐户登录中获得的索赔信息创建应用程序用户
?外部供应商的索赔将特定于该供应商。它不是登录到你应用程序中的本地身份存储,它只是声称知道用户是谁。因此,您需要将用户登录到您的存储(SignInManager),然后才能使用它进行授权。如果您不关心保护资源,只想了解用户,则可以直接映射到内部存储
标头中的声明需要由ASPNET“中间件”使用身份验证提供程序拦截,然后该提供程序将在HttpContext中设置用户对象。拥有用户后,需要将本地用户存储映射到学校帐户中的用户存储,然后从结果中单独调用索赔。通常,电子邮件是主题声明,可用于映射:
var userName = User.Identity.Name;
var user = _userManager.FindByNameAsync(userName);
var claims = _userManager.GetClaimsAsync(user);
外部供应商的索赔将针对该供应商。它不是登录到你应用程序中的本地身份存储,它只是声称知道用户是谁。因此,您需要将用户登录到您的存储(SignInManager),然后才能使用它进行授权。如果您不关心保护资源,只想了解用户,则可以直接映射到内部存储
标头中的声明需要由ASPNET“中间件”使用身份验证提供程序拦截,然后该提供程序将在HttpContext中设置用户对象。拥有用户后,需要将本地用户存储映射到学校帐户中的用户存储,然后从结果中单独调用索赔。通常,电子邮件是主题声明,可用于映射:
var userName = User.Identity.Name;
var user = _userManager.FindByNameAsync(userName);
var claims = _userManager.GetClaimsAsync(user);
这要归功于@poke
内部用于检索用户的用户id,然后用于从用户存储(即您的数据库)查询对象
GetUserId
基本上如下所示:
public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
因此,这将返回Options.ClaimsIdentity.UserIdClaimType
的索赔值<代码>选项
是您配置标识时使用的选项。默认情况下,UserIdClaimType
的值为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
声明类型:
// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimIdentity.UserIdClaimType = "UserID";
});
资料来源:
这要归功于@poke 内部用于检索用户的用户id,然后用于从用户存储(即您的数据库)查询对象
GetUserId
基本上如下所示:
public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
因此,这将返回Options.ClaimsIdentity.UserIdClaimType
的索赔值<代码>选项是您配置标识时使用的选项。默认情况下,UserIdClaimType
的值为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
声明类型:
// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimIdentity.UserIdClaimType = "UserID";
});
资料来源:
可能您需要刷新声明,因为新创建的用户可能还不存在。如果在数据库中创建的很好,请尝试使用
await\u-signInManager.RefreshSignInAsync(applicationUser)刷新声明调用await\u userManager.AddClaimsAsync(newUser,User.Claims)后的code>
@Dave这给了我以下错误:InvalidOperationException:没有为方案“Identity.Application”注册身份验证处理程序。注册计划有:AzureAD、AzureADOpenID、Azureadocookie。您是否忘记调用AddAuthentication()。添加[SomeAuthHandler](“Identity.Application”,…)?
。基于此,我想到了做wait\u userManager.AddLoginAsync(user,loginInfo)
。但我不知道如何找回日志