问题
I have a basic Identityserver4 implementation based on the quick start sample.
In my startup I have the following:
public void ConfigureServices(IServiceCollection services)
{
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
}
public void Configure(IApplicationBuilder app)
{
...
app.UseIdentityServer();
}
I want to extend the IdentityServer4 workflow so that after the access token is generated I can run business logic (based on the claims in the access token) and modify the response send to the calling client. I tried creating a .NET core middleware but it seems the IdentityServer middleware short-circuits the rest of the pipeline (no middleware place after the UseIdentityServer will be executed).
Are they any extension method in Identityserver4 that I can use to always modify the response issued by IdentityServer4? I am using the credentials grant. Essentially I want to run some business logic to modify the response send to the client once IdentityServer4 is done with its workflow
回答1:
Unfortunately, there is no way to do that. When you request any IdentityServer endpoint, IdentityServer middleware short-circuits the rest of the pipeline. You can check source code: IdentityServerMiddleware class.
I believe it was done for a reason. But if you really need to modify the response, you have at least three options:
- Create a fork and remove
return
operator fromIdentityServerMiddleware
Invoke
method (be careful to short-circuit the rest of the pipeline addingreturn
into your last middleware). - Create your own
IdentityServerMiddleware
,IdentityServerApplicationBuilderExtensions
implementations and use them instead of default. Place your middleware before the UseIdentityServer. Your middleware should look like this:
public ResponseBodyEditorMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { // 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(context); // get the body as a string var bodyString = Encoding.UTF8.GetString(buffer.GetBuffer()); // make some changes 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; }
来源:https://stackoverflow.com/questions/46284670/how-to-extend-identityserver4-workflow-to-run-custom-code