OpenIddict 支持通过 GET 请求返回授权码给邮递员

Posted

技术标签:

【中文标题】OpenIddict 支持通过 GET 请求返回授权码给邮递员【英文标题】:OpenIddict support returning authorization code via GET request for postman 【发布时间】:2022-01-12 09:11:08 【问题描述】:

我已经使用 OpenIddict 3.1.1 设置了授权服务器(移植到直接使用旧 ASOS 包的现有服务器)。我相信我已经成功了,因为在使用客户端应用程序时,我能够登录、给予同意、重定向回客户端,并用授权码交换访问令牌。

但是,当我尝试使用 Postman 的 OAuth 2.0 身份验证支持执行相同操作时,我能够登录(并表示同意),但是当它完成并返回授权代码时,我会收到来自 @987654321 的 HTTP 403 @ 我被重定向到:

403 错误 无法满足请求。 此分发未配置为允许用于此请求的 HTTP 请求方法。该发行版仅支持可缓存的请求。我们目前无法连接到此应用或网站的服务器。可能有太多流量或配置错误。请稍后再试,或联系应用或网站所有者。 如果您通过 CloudFront 向客户提供内容,则可以通过查看 CloudFront 文档找到解决问题的步骤并帮助防止出现此错误。 由云端(CloudFront)生成 请求 ID:UAXpago6ISiqbgm9U_SVPwh96qz1qoveZWFd0Cra-2FximeWZiY2aQ==

据我所知,这是因为 OpenIddict 正在向回调 url 发出 POST 请求。这适用于我的客户端应用程序,但 Postman 显然不支持。

我需要对 OpenIddict 进行哪些配置调整才能在邮递员中支持这一点?

Startup.ConfigureServices 中的 OpenIddict 相关配置:

services.AddOpenIddict()
        .AddCore(options =>  
            options.AddApplicationStore<ClientStore>();
            options.UseEntityFramework()
                .UseDbContext<OAuthServerDbContext>()
                .ReplaceDefaultEntities<Client, Authorization, OAuthScope, Token, long>()
        ;
        )
        .AddServer(options => 
            options.RegisterClaims();

            options.RegisterScopes(OpenIddictConstants.Scopes.OpenId,
                OpenIddictConstants.Scopes.Email,
                OpenIddictConstants.Scopes.OfflineAccess,
                OpenIddictConstants.Scopes.Profile,
                "user");

            // flows
            options.AllowAuthorizationCodeFlow();
            options.AllowRefreshTokenFlow();
            options.AllowPasswordFlow();
            options.AllowHybridFlow();
            // implicit is used by postman
            options.AllowImplicitFlow();

            var serviceProvider = options.Services.BuildServiceProvider();
            var oauthConstants = serviceProvider.GetRequiredService<IOptions<OAuthConstants>>().Value;
            var tokenLifetimes = serviceProvider
                .GetRequiredService<IOptions<OpenIdConnectServerTokenLifetimeSettings>>().Value;

            // security
            options.SetAccessTokenLifetime(tokenLifetimes.AccessTokenLifetime)
                .SetAuthorizationCodeLifetime(tokenLifetimes.AuthorizationCodeLifetime)
                .SetIdentityTokenLifetime(tokenLifetimes.IdentityTokenLifetime)
                .SetRefreshTokenLifetime(tokenLifetimes.RefreshTokenLifetime);

            options.SetIssuer(new Uri("https://localhost/oauth/"));

            // custom handlers added here
            options.AddEventHandlers();

            // certificate details hidden
            options.AddEncryptionCertificate(certificate);


            // endpoints
            options.SetAuthorizationEndpointUris("/OpenIdConnect/Authorize");
            options.SetLogoutEndpointUris("/OpenIdConnect/Logout", "/Account/Logout");

            options.SetRevocationEndpointUris("/OpenIdConnect/Revoke");
            options.SetTokenEndpointUris("/OpenIdConnect/Token");

            options.SetCryptographyEndpointUris("/OpenIdConnect/JWKDoc");
            options.SetUserinfoEndpointUris("/OpenIdConnect/UserInfo");

            options.UseAspNetCore()
                .EnableStatusCodePagesIntegration()
                .EnableAuthorizationEndpointPassthrough()
                //.EnableTokenEndpointPassthrough()
                .EnableLogoutEndpointPassthrough()
                .EnableUserinfoEndpointPassthrough()
                ;
        )
        .AddValidation(options => 
             options.UseLocalServer();

            options.UseAspNetCore();

            var serviceProvider = options.Services.BuildServiceProvider();

            var config = serviceProvider.GetRequiredService<IConfiguration>();
            options.SetClientId(config.GetValue<string>(nameof(Settings.OAuthClientId)));
            options.SetClientSecret(config.GetValue<string>(nameof(Settings.ClientSecret)));

            // certificate details hidden
            options.AddEncryptionCertificate(certificate);
        );

邮递员详情:

授权 代币名称:已编辑 授权类型:授权码 回调 URL:禁用,https://oauth.pstmn.io/v1/callback 使用浏览器授权:勾选 认证网址:https://localhost/oauth/OpenIdConnect/Authorize 访问令牌 URL:https://localhost/oauth/OpenIdConnect/Token 客户 ID:已编辑,但正确 客户机密:已编辑,但正确 范围:openid offline_access 状态: 客户端身份验证:在正文中发送客户端凭据

edit:它发送给邮递员回调 URI 的响应确实在正文中包含了授权码,但是由于 403 响应,邮递员没有将其解析出来并发出后续请求以交换代码令牌。

【问题讨论】:

一个想法是没有将 PostMan 重定向 URL 添加到 OpenIddict 中?或者如果是 HTTP 与 HTTPS 问题?我假设在 OpenIddict 中也需要将 Postman 添加为客户端。 它正在重定向和发送授权码,因此它会通过所有打开的iddict代码,包括客户端查找和重定向uri验证。我可以查看开发工具中的有效负载,它重定向的响应包含授权码。我会将此作为信息添加到帖子中。 【参考方案1】:

您可以设置一个选项来控制是在 URL 中作为查询字符串还是在正文中作为帖子接收授权代码。选项是 response_mode,您可以作为客户端进行控制。

我相信如果不设置为response_mode=form_post,那么你会得到URL中的代码。

查看此参数的详细信息here。

【讨论】:

谢谢,这帮助我找到了一些将 response_mode 默认为 form_post 的旧代码。 很高兴能帮上忙!

以上是关于OpenIddict 支持通过 GET 请求返回授权码给邮递员的主要内容,如果未能解决你的问题,请参考以下文章

WebApi Post 方法总是返回“请求的资源不支持 http 方法 'GET'。”状态:405 方法不允许

带有 ClientCredentials 流的 OpenIdDict 降级模式

JWT 授权重定向到登录

腾讯地图 webservice api get 请求 返回值 跨域

HTTP请求报文支持的各种方法

POST 请求不支持 Postman GET 请求