这对我来说是新事物,我仍在努力将其包裹住。我已经设置了IDP(Identity Server 4),并且能够配置客户端以对其进行身份验证(Angular 6 App),并且还可以配置客户端以进行API身份验证(Asp.Net Core 2.0)。一切似乎都很好。
这是IDP中的客户端定义:
new Client
{
ClientId = "ZooClient",
ClientName = "Zoo Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RequireConsent = true,
RedirectUris = { "http://localhost:4200/home" },
PostLogoutRedirectUris = { "http://localhost:4200/home" },
AllowedCorsOrigins = { "http://localhost:4200" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.Phone,
IdentityServerConstants.StandardScopes.Address,
"roles",
"ZooWebAPI"
}
}
我正在客户端中请求以下范围: 'openid个人资料电子邮件角色ZooWebAPI'
WebAPI的设置如下:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters()
.AddAuthorization();
services.AddCors();
services.AddDistributedMemoryCache();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://localhost:44317";
options.RequireHttpsMetadata = false;
options.ApiName = "ZooWebAPI";
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(policy =>
{
policy.WithOrigins("http://localhost:4200");
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.AllowCredentials();
policy.WithExposedHeaders("WWW-Authenticate");
});
app.UseAuthentication();
app.UseMvc();
}
通过使用[授权],我成功地保护了API:
[Route("api/[controller]")]
[Authorize]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public ActionResult Get()
{
return new JsonResult(User.Claims.Select(
c => new { c.Type, c.Value }));
}
}
一切正常,如果客户端未通过身份验证,浏览器将转到IDP,需要身份验证,使用访问令牌重定向回去,然后将访问令牌用于成功进行的API调用。
如果我查看User对象中的Claims,我可以看到一些信息,但是我没有任何用户信息。我可以看到范围等,但是没有角色。从我所读的内容中可以预料到,API不应该在乎用户正在调用什么,但是如何通过基于角色的API调用来限制我呢?还是完全违反规格?
IDP有一个userinfo端点,该端点返回所有用户信息,我认为可以在WebAPI中使用它,但是再次从阅读中看来,它的意图是要从WebAPI调用该端点。仅限客户。
无论如何,我想基于特定用户的角色来限制Web API调用。有人有任何建议,意见吗?另外,我想知道是什么用户在拨打电话,怎么办?
JWT示例:
谢谢
答案 0 :(得分:0)
根据我可以从您的信息中学到的东西,我可以告诉以下内容。
您正在通过外部提供程序登录:Windows身份验证。 您正在定义一些范围,以将某些内容传递给令牌,以指示对特定资源的访问。
您所说的User对象是从访问令牌中填充的User类。由于访问令牌默认情况下不包括用户个人资料声明,因此您不会在User对象上使用它们。这与直接使用Windows身份验证(在用户原则上提供用户名)不同。
您需要采取其他措施来根据用户登录提供授权。 您可以在其中添加授权逻辑的几点:
您可以根据在Identityserver的配置中定义的自定义范围来定义声明。恕我直言,这不是可取的,因为它是固定在登录方法上的,而不是用户登录的。
您可以使用ClaimsTransformation(请参见下面的链接)。这使您可以将声明添加到方法开始时可用的声明列表中。这有一个缺点(对某些人来说是肯定的),这些额外的声明不会被添加到访问令牌本身中,只有在评估令牌的后端,才可以在您的代码处理请求之前添加这些声明。
如何检索这些声明取决于您的业务要求。
如果需要用户信息,则必须调用Identityserver的userinfo端点至少知道用户名。这就是该端点的目的。在此基础上,您可以使用自己的逻辑来确定该用户拥有的“角色”。
例如,我们创建了一个单独的服务,可以根据用户和访问令牌中包含的范围来配置和返回“ Roles”声明。