问题描述
我有两个不同的客户端应用程序连接到相同的API客户端.我希望一个具有只读访问权限(仅获取呼叫"),另一个也能够写入(获取",放置",发布"和删除"呼叫).我应该如何做到这一点?
I have two different client applications that connect to the same API client. I want one to have readonly access (Get calls only) and the other to be able to write as well (Get, Put, Post, and Delete calls). How should I accomplish this?
最终解决方案:
这最终就是我所做的.重要的是要注意,此解决方案需要一个附加的库.
This is ultimately what I did. It is important to note that this solution requires an additional library.
https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation/或者 https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation
services.AddMvcCore(options =>
{
// require at least one of the scopes listed var policy =
ScopePolicy.Create("client_api_readonly", "client_api_fullaccess");
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddAuthorization(option =>
{
// where the attribute is set, require the following scope
option.AddPolicy("ApiFullAccess", p =>
p.RequireScope("client_api_fullaccess"));
});
推荐答案
在这种情况下,您可以使用范围配置客户端访问.作用域不应用于授权,但在这种情况下,您需要(并且可以)配置客户端对资源的访问.
In this case you can configure client access by using scopes. Scopes should not be used for authorization, but in this case you want (and can) configure the client access to the resource.
请注意,这不是直接授权.范围定义了资源中的一项功能.如果客户端无法请求范围,则客户端将被限制为已配置范围的一部分的功能.
Please note, this is not direct authorization. A scope defines a piece of functionality in the resource. When a client is not able to request a scope then the client is limited to the functionality that is part of the scope(s) that is configured.
但这仅适用于特定情况,因为这仅是一个客户端,并且不涉及(交互)用户.
But this only work for this particular case because this is a client only and there are no (interactive) users involved.
假设您有一个资源: myresource
.
此资源有两个范围,例如 myresource.read
和 myresource.write
.
And this resource has two scopes, e.g. myresource.read
and myresource.write
.
您现在可以配置 Client.AllowedScopes ,其中 client1 的范围为 myresource.read
,而 client2 的范围为范围 myresource.read
和 myresource.write
.
You can now configure Client.AllowedScopes, where client1 has scope myresource.read
and client2 has the scopes myresource.read
and myresource.write
.
确保在资源中实现两个作用域.您可以定义用于特定范围的策略:
Make sure you implement the two scopes in the resource. You can define policies that look for the certain scope:
services.AddAuthorization(option =>
{
option.AddPolicy("ReadAccess", p => p.RequireScope("myresource.read"));
option.AddPolicy("WriteAccess", p => p.RequireScope("myresource.write"));
});
并拒绝访问没有任何范围的客户端:
And deny access to clients that do not have any of the scopes:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.JwtBearerEvents = new JwtBearerEvents
{
OnTokenValidated = async context =>
{
var allowedScopes = new List<string> { "myresource.read" , "myresource.write" };
if (!context.Principal.Claims.Any(c => c.Type == "scope" && allowedScopes.Contains(c.Value)))
{
context.Fail("Invalid Scope");
}
}
};
});
在您的控制器中,您可以使用Authorize属性(例如,
In your controllers you can limit access based on the policies, using the Authorize attribute, e.g.
[Authorize("myresource.read")]
public class MyController : ControllerBase
这篇关于控制客户端访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!