希望有人可以提供帮助。
我有一个IdentityServer3设置,我们在现有项目中使用范围授权。
我们刚刚创建了一个位于.NET Core上的API应用程序,并且与此相关的一些问题以及如何使其按预期运行。
此API资源实际上是中间人。在客户端上请求令牌,然后令牌依次调用API。相当标准的模型。
我们希望使用授权来处理2种情况: 1.令牌有效 2.令牌对API资源的指定范围有效(例如[Authorize(Scope =“ Scope1”)])
但是,API似乎根本没有连接到IS3实例。
代码如下:
启动
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://identityserver3server";
//options.ApiSecret = "";
options.ApiName = "ApiName";
options.LegacyAudienceValidation = true;
});
options.ApiName-从我的阅读来看,这似乎是与范围相关的,但是在此级别上,我们不想在此级别上指定范围的要求,而是希望在控制器中执行此操作。 options.ApiSecret-甚至需要吗?
services.AddAuthorization(options =>
{
options.AddPolicy("Scope1", policy => policy.Requirements.Add(new HasScopeRequirement("Scope1", "")));
});
范围要求
public class HasScopeRequirement : IAuthorizationRequirement
{
public string Scope { get; }
public HasScopeRequirement(string scope, string issuer)
{
Scope = scope ?? throw new ArgumentNullException(nameof(scope));
}
}
public class HasScopeHandler : AuthorizationHandler<HasScopeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == "scope"))
return Task.CompletedTask;
var scopes = context.User.FindFirst(c => c.Type == "scope").Value.Split(' ');
if (scopes.Any(s => s == requirement.Scope))
context.Succeed(requirement);
return Task.CompletedTask;
}
}
从这里开始,我们可以执行以下操作:
控制器
[ApiController]
[Authorize("Scope1")]
public class PingController : ControllerBase
{
[HttpGet("ping")]
public async Task<ActionResult> Ping()
{
return Ok("Ping pong");
}
}