在没有原理的线程上使用Authorize属性时,Asp.net Core操作不会返回401吗?

时间:2019-02-10 14:48:43

标签: c# asp.net-core asp.net-core-2.0

我想自己使用机制在线程上添加一个原理,,这确实使我想起了旧的成员资格/表单身份验证机制。

因此,我成功地(成功地)创建了一个具有以下原则的请求:

MyAuthMiddleware.cs

public class MyAuthMiddleware
{
    private readonly RequestDelegate _next;


    public MyAuthMiddleware(RequestDelegate next )
    {
        _next = next;

    }


    public async Task Invoke(HttpContext httpContext)
    {
        var claims = new List<Claim>  
        {  
            new Claim("userId", "22222222")  
        };  
        ClaimsIdentity userIdentity = new ClaimsIdentity(claims ,"MyAuthenticationType");  
        ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

         httpContext.User = principal;
         await _next(httpContext);
    }
}

配置方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //app.UseAuthentication(); //removed it. I will set the thread manually
            if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

            app.UseMyAuthMiddleware(); // <---------- Myne

            app.UseMvc();
            app.Run(async context => { await context.Response.WriteAsync("Hello World!"); });
        }

这是控制器中的“动作” :(“通知授权”属性)

    [HttpGet]
    [Route("data")]
    [Authorize]
    public IActionResult GetData()
    {

        var a=User.Claims.First(f => f.Type == "userId");
        return new JsonResult(new List<string> {"a", "b",a.ToString() , User.Identity.AuthenticationType});
    }

好,让我们尝试调用此方法,请注意,此确实有效

enter image description here

那么问题出在哪里呢?

请注意,这里有一个[Authorize]属性。现在我们删除
 设置线程的原理(通过删除此行):

//httpContext.User = principal; // line is remarked

但是现在当我导航到:

http://localhost:5330/api/cities/data

我被重定向到:

http://localhost:5330/Account/Login?ReturnUrl=%2Fapi%2Fcities%2Fdata

但是我希望看到未授权的错误。

我一直在追捧WebApi。这不是网站,而是API。

问题:

为什么我看不到未授权错误?以及如何使其显示?

Nb是我的ConfigureServices:

 public void ConfigureServices(IServiceCollection services)
        {
             services.AddAuthentication( CookieAuthenticationDefaults.AuthenticationScheme ) 
                  .AddCookie( CookieAuthenticationDefaults.AuthenticationScheme,  a =>
                  {
                      a.LoginPath = "";
                      a.Cookie.Name = "myCookie";


                  });

            services.AddMvc();
        }

编辑

当前,我设法做到的是使用OnRedirectionToLogin:

enter image description here

但是,如果那样走,那将真的令人失望。我希望它就像webapi。

1 个答案:

答案 0 :(得分:4)

OnRedirectToLogin委托的默认实现类似于this

public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogin { get; set; } = context =>
{
    if (IsAjaxRequest(context.Request))
    {
        context.Response.Headers["Location"] = context.RedirectUri;
        context.Response.StatusCode = 401;
    }
    else
    {
        context.Response.Redirect(context.RedirectUri);
    }
    return Task.CompletedTask;
};

从上面的代码可以清楚地看到,发送到客户端的响应取决于IsAjaxRequest(...)的结果,其结果看起来像这样:

private static bool IsAjaxRequest(HttpRequest request)
{
    return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
        string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
}

这意味着如果将401请求标头或查询字符串值设置为X-Requested-With,则响应将是XMLHttpRequest重定向。当您直接从浏览器或例如从Fiddler,未设置此值,因此响应为302,如观察到的那样。否则,在浏览器中使用XHR或Fetch时,将为您设置此值作为标题,因此将返回401