簡體   English   中英

如何使用Asp.Net Web API 2中的Owin OAuth2修改令牌端點響應主體

[英]How to modify token endpoint response body with Owin OAuth2 in Asp.Net Web API 2

我想從令牌端點響應修改響應主體。

我試圖用MessageHandler攔截/ Token請求,但它不起作用。

我可以通過覆蓋OAuthAuthorizationServerProvider.TokenEndpoint方法為響應添加一些額外的信息,但是我無法創建自己的響應主體。

有沒有辦法攔截/ Token請求?


編輯

我發現了如何從令牌端點響應中刪除響應主體內容,如下所示: HttpContext.Current.Response.SuppressContent = true;

這似乎是實現我的目標的正確方法,但現在當我使用context.AdditionalResponseParameters.Add()方法添加我的自定義信息時, SuppressContent阻止任何改動。

現在我有這樣的事情:

// Removing the body from the token endpoint response
HttpContext.Current.Response.SuppressContent = true;
// Add custom informations
context.AdditionalResponseParameters.Add("a", "test");

要簡單地將新項添加到JSON令牌響應,您可以使用TokenEndpointResponse而不是TokenEndpoint通知。


如果您正在尋找一種方法來完全替換您自己的OAuth2授權服務器准備的令牌響應,那么很遺憾沒有簡單的方法可以做到這一點,因為OAuthAuthorizationServerHandler.InvokeTokenEndpointAsync在調用TokenEndpointResponse后不會檢查OAuthTokenEndpointContext.IsRequestCompleted屬性通知。

https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OAuth/OAuthAuthorizationServerHandler.cs

這是一個已知的問題,但是當我建議解決它時,將它包含在Katana 3中為時已晚。

您應該嘗試Owin.Security.OpenIdConnect.Server :它是為Katana 3.0和4.0設計的OAuthAuthorizationServerMiddleware的分支。

https://www.nuget.org/packages/Owin.Security.OpenIdConnect.Server/1.0.2

當然,它包括正確的檢查以允許繞過默認令牌請求處理(這甚至是我在分叉時修復的第一件事)。

你幾乎在那里+ Samoji @Samoji,真的幫助/啟發我得到答案。

// Add custom informations
context.AdditionalResponseParameters.Add("a", "test");
// Overwrite the old content
var newToken = context.AccessToken;
context.AdditionalResponseParameters.Add("access_token", newToken);

我發現它只是用我的舊代替了我的舊代幣。

此問題類似於如何擴展IdentityServer4工作流以運行自定義代碼

因此,您可以在Startup中創建自定義中間件並在OAuth2服務之前注冊它:

    public void Configuration(IAppBuilder app)
    {
        ....
        app.Use(ResponseBodyEditorMiddleware.EditResponse);

        app.UseOAuthAuthorizationServer(...);
        ...
    }

自定義中間件的位置是:

    public static async Task EditResponse(IOwinContext context, Func<Task> next)
    {
        // get the original body
        var body = context.Response.Body;

        // replace the original body with a memory stream
        var buffer = new MemoryStream();
        context.Response.Body = buffer;

        // invoke the next middleware from the pipeline
        await next.Invoke();

        // get a body as string
        var bodyString = Encoding.UTF8.GetString(buffer.GetBuffer());

        // make some changes to the body
        bodyString = $"The body has been replaced!{Environment.NewLine}Original body:{Environment.NewLine}{bodyString}";

        // update the memory stream
        var bytes = Encoding.UTF8.GetBytes(bodyString);
        buffer.SetLength(0);
        buffer.Write(bytes, 0, bytes.Length);

        // replace the memory stream with updated body
        buffer.Position = 0;
        await buffer.CopyToAsync(body);
        context.Response.Body = body;
    }

攔截請求和響應的最佳方法是通過MessageHandler,如果你想在請求到達管道中的IControllerFactory處理程序后避免這樣做 - 顯然在這種情況下使用自定義的'Attribute'

我過去曾使用MessageHandler攔截對api / token的請求,創建新請求並獲取響應,創建新響應。

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        //create a new auth request
        var authrequest = new HttpRequestMessage();
        authrequest.RequestUri = new Uri(string.Format("{0}{1}", customBaseUriFromConfig, yourApiTokenPathFromConfig));

        //copy headers from the request into the new authrequest
        foreach(var header in request.Headers)
        {
            authrequest.Headers.Add(header.Key, header.Value);
        }

        //add authorization header for your SPA application's client and secret verification
        //this to avoid adding client id and secret in your SPA
        var authorizationHeader =
            Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", _clientIdFromConfig, _secretKeyFromConfig)));

        //copy content from original request
        authrequest.Content = request.Content;

        //add the authorization header to the client for api token
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(request.Headers.Authorization.Scheme, authorizationHeader);
        var response = await client.PostAsync(authrequest.RequestUri, authrequest.Content, cancellationToken);

        if(response.StatusCode == HttpStatusCode.OK)
        {
            response.Headers.Add("MyCustomHeader", "Value");
            //modify other attributes on the response
        }

        return response;
    }

這對我很有用。 但是,WebApiConfig.cs文件中需要此處理程序的配置(如果您使用的是ASP.NET MVC,則為RouteConfig.cs)。

你能詳細說明在處理程序中對你不起作用的東西嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM