Bad*_*ake 4 openid oauth-2.0 openid-connect identityserver4
阅读 Open Id 文档后,我有一些疑问。任何帮助都感激不尽。
遵循任何oidc 流程,您都会获得一个 id_token 和一个 access_token。
a) 当您将 access_token 发送到受保护的 api 时,为什么或何时(示例)需要检索有关拥有它的用户的一些声明?也许受保护的 api 想要使用有关经过身份验证的用户的一些数据?
b) 为了获得声明,受保护的 api 需要与 UserEdnpoint 端点通信?它发送access_token?哪些声明包含在返回的 id_token 中?/ 如果它要求更多声明用户具有同意访问权限,会发生什么?
c) 身份服务器 4:您定义要保护的资源。它们可以是“身份资源”和“api 资源”。在定义 ApiResources 时,您可以在细粒度范围内定义。例如:
Scopes =
{
new Scope()
{
Name = "weather.api.full_access",
DisplayName = "Full access to WEATHER API",
},
new Scope
{
Name = "weather.api.read_only",
DisplayName = "Read only access to WEATHER API"
}
}
Run Code Online (Sandbox Code Playgroud)
您还定义了客户端,以及他们有权访问的范围。您如何指定哪些用户可以访问特定资源?我不知道您将如何映射使用同一客户端的用户的特定权限。
步骤将是:
非常感谢!!
Rua*_*urg 13
IdentityServer 包含三个部分:
有两个令牌:访问令牌和身份令牌。访问令牌用于访问资源(api 和 UserInfo 端点),身份令牌包含有关用户的信息。
虽然 IdentityServer 是关于对用户进行身份验证,但它也包含授权配置。您可以使用 PolicyServer 之类的东西从 IdentityServer 中获取授权,但对于基本授权,您不必这样做。
有两种类型的用户声明:
第一组声明是身份令牌的一部分,告诉客户端用户是谁,其他声明是访问令牌的一部分,告诉 API 用户可以做什么。
关于身份令牌,唯一可以指望的是它始终包含sub声明(用户表中的 Id)。这里的 filosophy 的简短版本是保持令牌小,因为您只需要那个声明。可以在 UserInfo 端点请求附加信息。身份令牌的内容可能会有所不同。例如,您可以强制将所有声明添加到第一个令牌 (AlwaysIncludeUserClaimsInIdToken) 以防止额外调用。
另一方面,如果用户选择不同意,那么身份令牌将保持为空(除了 sub 声明,因为 scope=openid 是必需的)。当从 UserInfo 端点请求时也是如此。
所以问题是,您将如何使用身份令牌?代币有多少价值?您不应该使用它来访问资源(这是访问令牌的用途),并且它可能不包含请求的信息。
关于访问令牌,这是实际上使客户端可以访问资源 (api) 的令牌。在 client_credentials 流中,没有用户(因此也不会有身份令牌),而在其他 flwos 中,客户端将代表用户进行操作。第一个流和其他流之间的区别在于sub声明。这告诉 Api 代表客户端请求访问的人。
对于访问令牌计数相同,如果用户不同意,则客户端将无法访问资源。
关于资源和范围。资源是资源的逻辑名称。我的意思是,您可能有多个属于同一资源的 Api。没关系。因为一种资源可以有多个作用域。在示例中,它是 1:1,但是当您真正使用作用域时,您会看到作用域实际上定义了资源中的某个功能。比如微服务。
回到 IdentityServer。IdentityServer 的一项重要工作是过滤声明。因为用户可以有很多声明,但您只在需要时才需要它们。因此,每个令牌都添加了请求的声明。
Identity Token 声明说明了用户是谁。但还有更多,这些声明与上下文无关。他们总是真实的。您的姓名在任何地方都相同,您的生日等也是如此。使用 IdentityResource 表来定义范围,例如 openid、profile、email。
访问令牌中的声明取决于上下文。因为只有 API 知道声明的含义。使用命名空间类型来区分声明。
Api 资源的设置方式并不重要,只要记住,当请求一个范围时,来自该资源的所有声明(包括该资源中的其他范围)都被添加到请求过滤器中,而当请求一个范围时,只有该范围的声明被添加到请求过滤器中。用于将来自用户的所有匹配声明添加到令牌的请求过滤器。
所以现在你有一个访问令牌。令牌必须包含有关范围的信息。为什么?因为您不希望客户端访问不允许的资源。通过定义每个客户端的范围来限制访问。由于范围是一项功能,您知道客户端需要哪些范围。在 IdentityServer 中,您配置相同的范围以匹配客户端。永远不要相信客户。
访问令牌包含来自请求的范围/资源的所有声明。这意味着使用该令牌可以使用该令牌访问资源/范围内的所有 api,而无需为每个 api 获取新令牌。
这也意味着令牌可以变得非常大。在达到限制之前你应该避免的事情。这就是为什么您不想要令牌中的权限。如果您需要权限,请实现您自己的授权服务器。
另一方面,您需要权限吗?给定一个设计,其中 Api(资源)知道允许用户访问什么,使用策略(某种业务规则)和基于资源的授权。您可以实现一个包含有关权限信息的本地用户表。
另外,您真的需要对每个对象都具有 CRUD 权限吗?使用策略,您有机会定义更复杂的授权,而不仅仅是比较字符串值。
对于用户,用户是身份的资源。但对作用域一无所知。所以你不能将范围绑定到用户。客户端有作用域,它打开了 api 的大门,但 api 决定用户是否真正拥有访问权限。
现在回答你的问题:
a) 来自用户的与请求的声明类型匹配的所有声明都被添加到访问令牌中。请求的声明类型取自请求的范围。添加与请求范围相关的所有 ApiResource 声明类型以及请求范围本身的声明类型。
如果 Api 需要有关用户的信息,则它可以使用访问令牌来调用 UserInfo 端点。默认身份令牌仅包含sub声明(用户无法拒绝或撤销的内容)。
b) 通过向客户端添加范围来请求令牌。默认情况下添加 openid,配置文件范围。客户端凭据不会收到身份令牌,并且有一个额外的令牌,即刷新令牌。请注意,并非所有流都可以使用此令牌。要请求刷新令牌,请添加offline_access范围。您可以在哪里离线访问文字。这是一个令牌,允许客户端请求新的访问令牌,而无需用户输入。因此,如果用户处于离线状态,服务仍然可以继续。
当需要用户同意时,某些信息或选项可能不可用。例如,如果用户不想离线访问,则服务(例如某些同步服务)将无法运行。当用户撤销给定的同意时也会发生这种情况。请求新的访问令牌将导致未经授权的响应。
为了绕过丢失的用户信息,只需向用户询问信息并将其存储在本地即可。无论如何,您很可能在那里需要它。
c) 忘记权限,使用策略和基于资源的授权。在 Api 中实现它。那是知道确切上下文的地方。客户端可以打开 api 的大门,但是否可以访问资源取决于用户(声明、本地授权信息)。
假设您有资源“weather”和范围“weather.api.full_access”和“weather.api.read_only”(作为资源“weather”的一部分)。
请注意,名称“weather.api.full_access”并未说明访问级别,仅说明预期功能。
实际访问级别应基于来自资源或策略的本地信息,例如用户具有读取订阅或管理员角色。
为了给 Billy 完全访问权限,向 Billy 添加http://api/admin (value: true) 声明。并为 Jhon 在订阅表中添加一条记录。
为了将资源划分到多个 api(每个范围),请使用事件来验证范围。当仅请求读取范围时,您不希望客户端访问 full_access 功能。
我希望这对你有意义。很难给出一个简短而完整的答案。如果您对此答案有任何疑问,请告诉我。
总之,IdentityServer 可以实现这一切。如果您需要权限,请查看策略服务器。
| 归档时间: |
|
| 查看次数: |
2927 次 |
| 最近记录: |