首页 > 解决方案 > 如何将 acr_values 添加到 /user/connect/token 请求正文?(.net 核心)

问题描述


我正在尝试从我的身份验证服务器获取机密用户的令牌。我创建了一个 .NET Core MVC 应用程序并使用 OAuthExtensions.AddOAuth 方法来添加身份验证服务。

要获取令牌,我需要将 acr_values 发送到 AuthorizationEndpoint 和 TokenEndpoint。我在 AuthorizationEndpoint 请求参数中发现了如何发送它,但我不知道如何将 acr_values 添加到 TokenEndpoint 请求正文中。
谁能帮我这个?

我的 Startup.cs(配置服务):

...
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "ClientCookie";
    options.DefaultSignInScheme = "ClientCookie";
    options.DefaultChallengeScheme = "OurServer";
})
.AddCookie("ClientCookie") // cookie authentication middleware first
.AddOAuth("OurServer", options =>
{
    options.CallbackPath = new PathString("/my-redirect-path");
    options.ClientId = "ClientId";
    options.ClientSecret = "ClientSecret";
    options.AuthorizationEndpoint = "https://example.com/user/connect/authorize";
    options.TokenEndpoint = "https://example.com/user/connect/token";
    options.UserInformationEndpoint = "https://example.com/user/connect/userinfo";

    options.Events = new OAuthEvents
    {
        OnRedirectToAuthorizationEndpoint = (context) =>
        {
            context.RedirectUri +=
                "&acr_values=myAcrValues&login_hint=myLoginHint@example.com";
            context.Response.Redirect(context.RedirectUri);
            return Task.CompletedTask;
        },
    };

});
...

标签: c#.netauthentication.net-coreoauth

解决方案


我找到了解决方案。
第 1 步:覆盖 DelegatingHandler

public class CustomAuthorizingHandler : DelegatingHandler
{
    private readonly OAuthOptions _options;
    public CustomAuthorizingHandler(HttpMessageHandler inner, OAuthOptions options) : base(inner)
    {
        this._options = options;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.RequestUri == new Uri(_options.TokenEndpoint))
        {
            string appendData = $"acr_values=myAcrValues&";
            var content = request.Content.ReadAsStringAsync().Result;
            var cntn = QueryHelpers.ParseQuery(appendData + content);

            var dict = new Dictionary<string, string>();
            foreach (var c in cntn)
            {
                dict.Add(c.Key, c.Value[0]);
            }

            request.Content = new FormUrlEncodedContent(dict);
            request.Method = HttpMethod.Post;
        }
        return base.SendAsync(request, cancellationToken);
    }
}

第 2 步:将其添加到 Startup.cs ConfigureServices 中的选项中

...
services..AddOAuth("OurServer", options =>
{
    ...
    options.BackchannelHttpHandler = new CustomAuthorizingHandler(new HttpClientHandler(), options);

推荐阅读