Based on Greg P's original answer,有一些修改
第 1 步:创建一个充当中间件的类
using AppFunc = System.Func<System.Collections.Generic.IDictionary<string, System.Object>,
System.Threading.Tasks.Task>;
命名空间 SignOnAPI.Middleware.ResponseMiddleware
{
public class ResponseMiddleware
{
AppFunc _next;
ResponseMiddlewareOptions _options;
public ResponseMiddleware(AppFunc nex, ResponseMiddlewareOptions options)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
var context = new OwinContext(environment);
await _next(environment);
if (context.Response.StatusCode == 400 && context.Response.Headers.ContainsKey("Change_Status_Code"))
{
//read the status code sent in the response
var headerValues = context.Response.Headers.GetValues("Change_Status_Code");
//replace the original status code with the new one
context.Response.StatusCode = Convert.ToInt16(headerValues.FirstOrDefault());
//remove the unnecessary header flag
context.Response.Headers.Remove("Change_Status_Code");
}
}
}
Step2:创建扩展类(可省略)。
这一步是可选的,可以修改为接受可以传递给中间件的选项。
public static class ResponseMiddlewareExtensions
{
//method name that will be used in the startup class, add additional parameter to accept middleware options if necessary
public static void UseResponseMiddleware(this IAppBuilder app)
{
app.Use<ResponseMiddleware>();
}
}
第 3 步:在您的 OAuthAuthorizationServerProvider 实现中修改 GrantResourceOwnerCredentials 方法
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
if (<database connection failed)
{
//first reject the context, to signify that the client is not valid
context.Rejected();
//set the error message
context.SetError("invalid_username_or_password", "Invalid userName or password" );
//add a new key in the header along with the statusCode you'd like to return
context.Response.Headers.Add("Change_Status_Code", new[] { ((int)HttpStatusCode.InternalServerError).ToString() });
return;
}
}
Step4:在启动类中使用这个中间件
public void Configuration(IAppBuilder app)
{
app.UseResponseMiddleware();
//configure the authentication server provider
ConfigureOAuth(app);
//rest of your code goes here....
}