IDeneityServer4 授权逻辑

授权逻辑

OpenID Connect/OAuth 令牌服务的最终工作是控制对资源的访问。

  • IDentityServer 主要是基于资源授权,有两种资源:

    • identity resources: 代表关于用户的声明,如用户 ID、显示名称、电子邮件地址等……
      • 身份资源是一组命名的声明,可以使用 scope 参数进行请求。
    • API resources: 代表客户想要访问的功能。 通常,它们是基于 HTTP 的端点(又名 API),但也可以是消息队列端点或类似端点。
  • 客户端:客户端表示可以从您的 IdentityServer 请求令牌的应用程序

  • 客户端定义以下通用设置:

    • 唯一的客户端 ID
    • 密钥(如果需要的话)
    • 允许与令牌服务的交互(称为授权类型)
    • 身份和/或访问令牌被发送到的网络位置(称为重定向 URI)
    • 允许客户端访问的 scopes(又名 resources)列表(可以设置为身份资源和API资源的字符串名称)

    我们可以看到,客户端设置了允许它自己访问的 scopes 列表(资源列表),所以:

    • 用户登录客户端后,客户端会给用户颁发一个令牌
    • 客户端能访问的资源列表,用户通通可以访问

基于 Scopes 的授权

我们可以先定义多个 scopes , 例如:

public static IEnumerable<ApiScope> GetApiScopes()
{
    return new List<ApiScope>
    {
        // 发票 API 特有的 scopes
        new ApiScope(name: "invoice.read",   displayName: "读取您的发票。"),
        new ApiScope(name: "invoice.pay",    displayName: "支付您的发票。"),

        // 客户 API 特有的 scopes
        new ApiScope(name: "customer.read",    displayName: "读取您的客户信息。"),
        new ApiScope(name: "customer.contact", displayName: "允许联系您的客户之一。"),

        // 共享 scope
        new ApiScope(name: "manage", displayName: "提供对发票和客户数据的管理访问。")
    };
}

然后定义资源,设置资源允许访问的 scopes,例如:

public static readonly IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("invoice", "发票 API")
        {
           // 具有这几个 scopes  的客户端,可以访问我们的 api 资源
            Scopes = { "invoice.read", "invoice.pay", "manage" }
        },

        new ApiResource("customer", "客户 API")
        {
            Scopes = { "customer.read", "customer.contact", "manage" }
        }
    };
}

然后定义客户端,设置客户端允许访问的 scopes,例如;

public class Clients
{
    public static IEnumerable<Client> Get()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "service.client",
                ClientSecrets = { new Secret("secret".Sha256()) },

                AllowedGrantTypes = GrantTypes.ClientCredentials,

                // 这个客户端,通过设置了可以访问的 scopes
                // 所以这个客户端可以访问以上定义的两个资源
                AllowedScopes = { "invoice.read", "customer.read" }
            }
        };
    }
}

因此,一个更完整的IdentityServer授权流程可能包括以下几个步骤:

  • 定义Scopes:Scopes代表了可以授予客户端的权限的集合。在IdentityServer中,您需要定义哪些Scopes是有效的,并指定它们所代表的权限。
  • 资源关联到Scopes:受保护的资源(如API或服务)需要与一个或多个Scopes关联起来。这确保了只有持有相应Scope的客户端才能访问这些资源。
  • 客户端关联到Scopes:在IdentityServer中注册的客户端也需要与Scopes关联。这决定了哪些客户端有权请求哪些Scopes,进而访问相关的资源。
  • 用户身份验证:在客户端尝试访问资源之前,用户需要通过IdentityServer进行身份验证。这通常涉及用户名/密码、外部身份提供者等认证方式。
  • 令牌请求与验证:一旦用户身份验证成功,客户端会请求一个令牌(Access Token或ID Token),其中包含了用户的声明信息和授权Scopes。这个请求会发送到IdentityServer,IdentityServer会根据客户端的注册信息和用户的权限来决定是否颁发令牌。
  • 资源访问:客户端使用获得的令牌来访问受保护的资源。资源服务器会验证令牌的有效性,并检查其中包含的Scopes是否与它所保护的资源匹配。如果匹配成功,资源服务器会允许客户端访问资源。
posted @ 2024-06-23 12:49  RafaelLxf  阅读(32)  评论(0)    收藏  举报