我想从令牌端点响应中修改响应主体。
我尝试使用MessageHandler拦截 / Token 请求,但它无法正常工作。
我可以通过覆盖OAuthAuthorizationServerProvider.TokenEndpoint
方法为响应添加一些其他信息,但我无法创建自己的响应正文。
有没有办法拦截 /令牌请求?
我发现了如何从令牌端点响应中删除响应正文内容,如下所示: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");
答案 0 :(得分:5)
要简单地向JSON令牌响应中添加新项,您可以使用TokenEndpointResponse
代替TokenEndpoint
通知。
如果您正在寻找一种方法来完全替换您自己的OAuth2授权服务器准备的令牌响应,那么很遗憾没有简单的方法可以做到这一点,因为OAuthAuthorizationServerHandler.InvokeTokenEndpointAsync
没有&# 39;在调用OAuthTokenEndpointContext.IsRequestCompleted
通知后检查TokenEndpointResponse
属性。
这是一个众所周知的问题,但是当我建议修复它时,将它包含在Katana 3中为时已晚。
您应该尝试Owin.Security.OpenIdConnect.Server
:它是为Katana 3.0和4.0设计的OAuthAuthorizationServerMiddleware
的分支。
https://www.nuget.org/packages/Owin.Security.OpenIdConnect.Server/1.0.2
当然,它包括正确的检查以允许绕过默认令牌请求处理(这甚至是我在分叉时修复的第一件事)。
答案 1 :(得分:0)
你几乎就在那里+ Samoji @Samoji,真的帮助/激励我得到答案。
// Add custom informations
context.AdditionalResponseParameters.Add("a", "test");
// Overwrite the old content
var newToken = context.AccessToken;
context.AdditionalResponseParameters.Add("access_token", newToken);
我发现它只是用我的旧代码替换了旧代码。
答案 2 :(得分:-1)
此问题与How to extend IdentityServer4 workflow to run custom code
类似因此,您可以在启动中的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;
}
答案 3 :(得分:-2)
拦截请求和响应的最佳方法是通过MessageHandler,如果你想在请求到达管道中的IControllerFactory处理程序后避免这样做 - 显然在这种情况下使用自定义&#39;属性&#39;
我过去曾使用MessageHandlers拦截对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。)
你能详细说明在处理程序中对你不起作用的东西吗?