简体   繁体   English

如何使用Asp.Net Web API 2中的Owin OAuth2修改令牌端点响应主体

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

I want to modify the response body from the token endpoint response. 我想从令牌端点响应修改响应主体。

I've tried to intercept the /Token request with a MessageHandler but it doesn't work. 我试图用MessageHandler拦截/ Token请求,但它不起作用。

I'm able to add some additional informations to the response by overriding the OAuthAuthorizationServerProvider.TokenEndpoint method, but I'm not able to create my own response body. 我可以通过覆盖OAuthAuthorizationServerProvider.TokenEndpoint方法为响应添加一些额外的信息,但是我无法创建自己的响应主体。

Is there a way to intercept the /Token request? 有没有办法拦截/ Token请求?


Edit 编辑

I found out how to remove the response body content from the token endpoint response, like this: HttpContext.Current.Response.SuppressContent = true; 我发现了如何从令牌端点响应中删除响应主体内容,如下所示: HttpContext.Current.Response.SuppressContent = true;

It seems the right way to achieve my goal, but now when I use the context.AdditionalResponseParameters.Add() method to add my custom information, the SuppressContent block any alterations. 这似乎是实现我的目标的正确方法,但现在当我使用context.AdditionalResponseParameters.Add()方法添加我的自定义信息时, SuppressContent阻止任何改动。

Now I have something like this: 现在我有这样的事情:

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

To simply add new items to the JSON token response, you can use TokenEndpointResponse instead of the TokenEndpoint notification. 要简单地将新项添加到JSON令牌响应,您可以使用TokenEndpointResponse而不是TokenEndpoint通知。


If you're looking for a way to completely replace the token response prepared by the OAuth2 authorization server by your own one, there's sadly no easy way to do that because OAuthAuthorizationServerHandler.InvokeTokenEndpointAsync doesn't check the OAuthTokenEndpointContext.IsRequestCompleted property after invoking the TokenEndpointResponse notification. 如果您正在寻找一种方法来完全替换您自己的OAuth2授权服务器准备的令牌响应,那么很遗憾没有简单的方法可以做到这一点,因为OAuthAuthorizationServerHandler.InvokeTokenEndpointAsync在调用TokenEndpointResponse后不会检查OAuthTokenEndpointContext.IsRequestCompleted属性通知。

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

This is a known issue, but it was too late to include it in Katana 3 when I suggested to fix it. 这是一个已知的问题,但是当我建议解决它时,将它包含在Katana 3中为时已晚。

You should give Owin.Security.OpenIdConnect.Server a try: it's an a fork of the OAuthAuthorizationServerMiddleware designed for Katana 3.0 and 4.0. 您应该尝试Owin.Security.OpenIdConnect.Server :它是为Katana 3.0和4.0设计的OAuthAuthorizationServerMiddleware的分支。

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

Of course, it includes the correct check to allow bypassing the default token request processing (this was even one of the first things I fixed when forking it). 当然,它包括正确的检查以允许绕过默认令牌请求处理(这甚至是我在分叉时修复的第一件事)。

You were almost there +Samoji @Samoji and really helped/inspired me to get the answer. 你几乎在那里+ Samoji @Samoji,真的帮助/启发我得到答案。

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

I found it just replaced my old token with my new. 我发现它只是用我的旧代替了我的旧代币。

This question is similar to How to extend IdentityServer4 workflow to run custom code 此问题类似于如何扩展IdentityServer4工作流以运行自定义代码

So you can create custom middleware and register it before OAuth2 service in Startup: 因此,您可以在Startup中创建自定义中间件并在OAuth2服务之前注册它:

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

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

where custom middleware is: 自定义中间件的位置是:

    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;
    }

The best way to intercept request and response is via MessageHandler if you want to avoid doing so after a request has reached the IControllerFactory handler in the pipeline - obviously in that case use a custom 'Attribute' 拦截请求和响应的最佳方法是通过MessageHandler,如果你想在请求到达管道中的IControllerFactory处理程序后避免这样做 - 显然在这种情况下使用自定义的'Attribute'

I have used MessageHandlers in the past to intercept request to api/token, create a new request and get the response, create a new response. 我过去曾使用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;
    }

This works for me perfectly. 这对我很有用。 There is, however, the configuration for this handler required in the WebApiConfig.cs file (RouteConfig.cs if you're using ASP.NET MVC). 但是,WebApiConfig.cs文件中需要此处理程序的配置(如果您使用的是ASP.NET MVC,则为RouteConfig.cs)。

Can you elaborate on what it is that does not work for you on the handler? 你能详细说明在处理程序中对你不起作用的东西吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将ASP.NET Core WEB API令牌身份验证与OWIN / Katana OAuth 2.0授权服务器一起用作资源服务器 - Use ASP.NET Core WEB API token authentication as a resourceserver with OWIN/Katana OAuth 2.0 Authorization Server 使用RestSharp,如何使用oAuth2 Bearer令牌执行对ASP.NET Web API的POST请求? - Using RestSharp, how do I execute a POST request to my ASP.NET Web API with an oAuth2 Bearer token? 在幕后,如何跟踪 RefreshTokens? (ASP.NET 欧文/OAuth2) - Under the covers, how are RefreshTokens kept track of? (ASP.NET Owin/OAuth2) asp.net Web表单中的oauth2 - oauth2 in asp.net web forms 如何使用ASP.net MVC使用oauth2授权使用web api? - How to consume a web api with oauth2 authorization using ASP.net MVC? 如何在Asp.net MVC中编写OAuth2 Web API客户端 - How to write OAuth2 Web API Client in Asp.net MVC 实现Identity 2.1 + OWIN OAuth JWT承载令牌时如何从Web API控制器端点进行身份验证 - How to authenticate from Web API controller endpoint when implementing Identity 2.1 + OWIN OAuth JWT bearer token 具有承载令牌和角色更改的ASP.net OWIN OAuth中间件 - ASP.net OWIN OAuth middleware with bearer token and changing roles 如何使用ASP.Net Web API创建接受请求正文中任何内容类型的终结点 - How to create an endpoint that accepts any content type in the request body using ASP.Net Web API ASP.NET OWIN Middleware - 修改 HTTP 响应 - ASP.NET OWIN Middleware - modify HTTP response
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM