C# 在拒绝令牌请求时自定义OWIN/OAuth HTTP状态代码

C# 在拒绝令牌请求时自定义OWIN/OAuth HTTP状态代码,c#,.net,http,oauth,owin,C#,.net,Http,Oauth,Owin,为了验证客户端和资源所有者,我进行了派生 当我验证资源所有者时,我发现他们的凭据无效,我调用context.Rejected(),,HTTP响应附带HTTP/400错误请求状态代码,而我希望HTTP/401未经授权 如何自定义OAuthAuthorizationServerProvider的响应HTTP状态码?这就是我们覆盖Owin中间件的方式…首先,我们在Owin之上创建了自己的中间件…我认为我们遇到了与您类似的问题 首先需要创建一个常量: public class Constants {

为了验证客户端和资源所有者,我进行了派生

当我验证资源所有者时,我发现他们的凭据无效,我调用
context.Rejected()
,HTTP响应附带HTTP/400错误请求状态代码,而我希望HTTP/401未经授权


如何自定义OAuthAuthorizationServerProvider的响应HTTP状态码?

这就是我们覆盖Owin中间件的方式…首先,我们在Owin之上创建了自己的中间件…我认为我们遇到了与您类似的问题

首先需要创建一个常量:

public class Constants
{
    public const string OwinChallengeFlag = "X-Challenge";
}
我们覆盖了OwinMiddleware

public class AuthenticationMiddleware : OwinMiddleware
{
    public AuthenticationMiddleware(OwinMiddleware next) : base(next) { }

    public override async Task Invoke(IOwinContext context)
    {
        await Next.Invoke(context);

        if (context.Response.StatusCode == 400 && context.Response.Headers.ContainsKey(Constants.OwinChallengeFlag))
        {
            var headerValues = context.Response.Headers.GetValues(Constants.OwinChallengeFlag);
            context.Response.StatusCode = Convert.ToInt16(headerValues.FirstOrDefault());
            context.Response.Headers.Remove(Constants.OwinChallengeFlag);
        }

    }
}
在startup.Auth文件中,我们允许重写Invoke Owin命令

public void ConfigureAuth(IAppBuilder app)
    ....
        app.Use<AuthenticationMiddleware>(); //Allows override of Invoke OWIN commands
    ....

    }
public void ConfigureAuth(IAppBuilder应用程序)
....
app.Use()//允许重写调用OWIN命令
....
}
在ApplicationAuthProvider中,我们修改了GrantResourceOwnerCredentials

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        using (UserManager<IdentityUser> userManager = _userManagerFactory())
        {
            IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                context.Response.Headers.Add(Constants.OwinChallengeFlag, new[] { ((int)HttpStatusCode.Unauthorized).ToString() }); //Little trick to get this to throw 401, refer to AuthenticationMiddleware for more
                //return;
            }
            ....
public override异步任务GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext)
{
使用(UserManager UserManager=\u userManagerFactory())
{
IdentityUser user=await userManager.FindAsync(context.UserName,context.Password);
if(user==null)
{
SetError(“无效的授权”,“用户名或密码不正确”);
context.Response.Headers.Add(Constants.OwinChallengeFlag,new[]{((int)HttpStatusCode.Unauthorized).ToString()});//要使其抛出401,请参阅AuthenticationMiddleware了解更多信息
//返回;
}
....

我采用了稍微不同的方法,使用了
系统、安全、身份验证、身份验证异常和异常中间件

AuthenticationServerProvider:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        using (UserManager<IdentityUser> userManager = _userManagerFactory())
        {
            IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                throw new AuthenticationException("The user name or password is incorrect.");
            }
            ....
应用程序配置:

public void Configure(IAppBuilder app)
    ....
        app.Use<ExceptionMiddleware>();
        // Configure auth here
    ....

    }
public void配置(IAppBuilder应用程序)
....
app.Use();
//在此处配置身份验证
....
}
结果是:


我明天会试试,我会确认它是否对我有效!!提前谢谢;)嘿,我尝试了你的方法,发现了一些问题。我猜
STTIAuthenticationMiddleware
AuthenticationMiddleware
,我的主要问题是在我的管道中从未调用自定义中间件。我已经配置了中间件使用
app.Use()
app.Use(System.Type)
的软件。怎么了?是的,绝对正确。认为身份验证已经在工作。我只想在拒绝身份验证时将400更改为401。我设法使中间件工作(这是关于中间件在应用中注册的顺序…).BTW,当设置401代码时,响应仍然是HTTP/400。当在app.useAuthoritionServer之前写入app.Use()时,答案有效。
public void Configure(IAppBuilder app)
    ....
        app.Use<ExceptionMiddleware>();
        // Configure auth here
    ....

    }