如何正确使用Identity Server 4的内省端点?

35

我正在使用Identity Server 4,尝试使用introspection端点,但仅凭文档我无法理解。

文档只给出了这个示例。

POST /connect/introspect
Authorization: Basic xxxyyy

token=<token>

现在,为什么会有基本身份验证,xxxyyy应该是什么?我的应用程序中没有设置基本身份验证。我只是按照以下步骤使用ASP.NET Core设置了Identity Server 4的ConfigureServices

services.AddIdentityServer()
            .AddTemporarySigningCredential()
            .AddInMemoryApiResources(ApiResourceProvider.GetAllResources())
            .AddAspNetIdentity<Usuario>();

并在配置

app.UseIdentity();
app.UseIdentityServer();

我现在尝试使用一个POST请求到/connect/introspect,请求body中只包含token=<token>,但是返回了404错误。

我觉得我还是没有理解。

在ASP.NET Core中,我们如何使用Identity Server 4的introspection端点?


你想通过内省端点实现什么目标? - Shaun Luttin
2
我正在尝试验证令牌的有效性。我的意思是,令牌可能已过期,或者根本不是有效的令牌。我想能够使用它来验证这一点。我搜索了一下,发现内省端点是实现此目的的方法,但我并不真正明白如何使用它。 - user1620696
3个回答

65

IdSvr4的实现非常棒,但文档还有很大的改进空间 - 我花了一个小时在互联网上搜索才能找到可行的解决方案。如果你对一个概念还不熟悉,被告知“阅读规范”并不总是有帮助的 - 这在他们的论坛上经常发生。

所以 - 在POST /connect/introspect中需要传递一个scope secret

您可以通过更改config.cs类来配置快速入门。如果您已自定义数据存储库或未使用快速入门,则需要更新其内容 - 但是这个概念应该(希望如此)很清楚。

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("MyResource", "My_Resource_DisplayName")
        {
            ApiSecrets = new List<Secret>
            {
                new Secret("hello".Sha256())
            },
            Scopes=
            {
                new Scope("MY_CUSTOM_SCOPE")
            }
        }
    };
}

现在...

  1. 确保你的客户端拥有作用域 MY_CUSTOM_SCOPE
  2. 在获取承载令牌时,确保已请求了作用域 MY_CUSTOM_SCOPE

现在,按照以下方式对 API 资源名称和密码进行 Base64 编码:

Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", userName, password)));

其中,username 是 MyResource,password 是明文 hello(当然应该使用你自己的值!)- 应该最终生成一个类似这样的字符串:TXlSZXNvdXJjZTpoZWxsbw==

现在,你可以向 IDSvr4 发送 POST 请求...

POST /connect/introspect
Authorization: Basic TXlSZXNvdXJjZTpoZWxsbw==
Accept: application/json
Content-Type: application/x-www-form-urlencoded

token=<YOUR_TOKEN>

只要您的令牌具有作用域MY_CUSTOM_SCOPE(或者您称之为其他任何名称)- 您现在应该能够使用IdSvr的内省端点来获取有关其信息。


3
我同意。社区还有很多需要改进的地方。我也不得不自己摸索。 - Tobias Punke
谢谢你,这节省了我很多时间。应该将其标记为答案。 - jmichas
3
你所说的,“阅读规格说明”比起你在这里的解释要少得多用处。 - Matt Whitfield
10
没有文件记录这件事是不可原谅的。据我所知,规范(RFC 6749 2.3.1节)实际上描述了一种完全不同的实现(可选)。IdentityServer4本身很棒,但那些人过于追求咨询收益了。 - McGuireV10
请注意,如果您正在使用 IdentityModel 库与 HttpClient,则可以在创建客户端对象后直接调用 SetBasicAuthenticationOAuth(scopename, secret),而无需自己进行编码。 - McGuireV10
显示剩余3条评论

9

7
为了进一步解释@leastprivilege的回答:您需要对字符串"[yourApiName]:[yourApiSecret]"进行base64编码,并将其作为Authorization头部的basic值使用。请注意,不要改变原始意思。 - Mashton

2

@Jay的答案对我帮助很大。在我的情况下,我忘记了根据RFC 7662更改内容类型为url-encoded。

r.Header.Add("Content-Type", "application/x-www-form-urlencoded")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接