我目前正在建立一个带有Web API和MVC UI的新项目(最终还会有一个移动用户界面,可以与同一个API通信)。
所以,我有以下计划:
这意味着身份服务器只是一个身份服务器(意味着我允许人们通过Google等登录,而不必担心他们的角色和权限)。
所以,要实现上述目标,我需要检查用户对API的权限,而不是客户端(客户端可以是任何东西 - 网络,手机应用程序,JavaScript客户端等等,所以我们不能依赖它处理用户权限。)
在API上,我实现了Permissionhandler和PermissionRequirement授权策略。因此,在API控制器或方法上,我可以执行以下操作:[Authorize(Policy =“CreateUser”)]。看起来我需要根据系统权限制定策略。
所以在授权处理程序中我需要:
在我尝试从身份服务器请求用户的用户名之前,情况一直很顺利。我知道我需要使用UserInfoClient来做到这一点,但我无法弄清楚如何使用用户的令牌/凭证从身份服务器获取他们的声明或至少获取他们的User.Identity.Name。
现在我可以使用子ID将用户添加到应用程序数据库,但是无论谁管理权限都不知道那个人是谁,所以我需要真正使用他们的电子邮件。
现在在MVC客户端中,我可以看到User.Identity.Name没有任何问题,但在API中该值为null!?
所以我的问题是:我如何从API中获取当前用户的Identity.Name,用户名或电子邮件?
感谢。
答案 0 :(得分:3)
想想我现在已经破解了它。
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
if (mvcContext != null)
{
// Use the UserInfo endpoint to get the user's claims
var discoveryClient = new DiscoveryClient("http://localhost:5000");
var doc = await discoveryClient.GetAsync();
var accessToken = await mvcContext.HttpContext.Authentication.GetTokenAsync("access_token");
var userInfoClient = new UserInfoClient(doc.UserInfoEndpoint);
var response = await userInfoClient.GetAsync(accessToken);
var claims = response.Claims;
}
详细信息位于https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies的底部,因此根据Microsoft的说法,这是正确的方法。
然而你确实激发了这个想法,谢谢你。几个小时我一直盯着这个血腥的东西。你有时需要的只是别人说些什么,什么,诅咒都破了! :)
如果有人有,我仍然愿意接受更好的方法。
干杯
答案 1 :(得分:2)
我相信您已经在 Web API 中配置 IdentityServerAuthentication ,类似this -
rotate=90
当您拨打网络服务电话时,您需要传递从 IdentityServer 收到的 令牌 <比如this -
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://UrlOfIentityServer",
RequireHttpsMetadata = false,
ApiName = "exampleapi"
});
...
}