首页 文章

如何使用Microsoft.Owin.Security自定义System.Web.Http.AuthorizeAttribute?

提问于
浏览
3

我在WebAPI中实现了自定义AuthorizeAttribute(请注意,这与MVC AuthorizeAttribute不同) .

我已经覆盖了OnAuthorization方法 . 在此方法中,我检查用户是否已通过身份验证 . 如果未经过身份验证,我会质疑用户登录 .

我的自定义逻辑的一部分是检查经过身份验证的用户是否有权继续(基本上我检查他们的名字/电子邮件 . 如果它存在于预定义列表中,那么他们有权访问) .

我看到的问题是:在用户成功验证BUT FAILS被授权后,我看到有一个无限循环重定向到登录页面 .

同样,用户凭据的挑战在OnAuthorization方法中 . 什么可能导致这种无限循环,以及一旦确定用户没有授权,如何防止这种情况?

*** Updated with snippet ***

public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
    base.OnAuthorization(actionContext); // Should this be here?

    var owinContext = HttpContext.Current.GetOwinContext();
    var authenticated = owinContext.Authentication.User.Identity.IsAuthenticated;
    var request = System.Web.HttpContext.Current.Request;

    if (!authenticated)
    {    
        // Challenge user for crednetials
        if (!request.IsAuthenticated)
        {
            // This is where the user is requested to login.
            owinContext.Authentication.Challenge(
                new AuthenticationProperties { RedirectUri = "/" },
                WsFederationAuthenticationDefaults.AuthenticationType);
        }
    }
    else
    {
        // At this point the user ia authenticated.
        // Now lets check if user is authorized for this application.
        var isAuthorized = SecurityHelper.IsUserAuthorized();
        if (isAuthorized)
        {
            // authorized.
            return;
        }

        // not authorized.
        actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
    }
}

2 回答

  • 1

    您可以尝试删除OnAuthorization并添加以下内容:

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        var owinContext = HttpContext.Current.GetOwinContext();
        var authenticated = owinContext.Authentication.User.Identity.IsAuthenticated;
    
        return authenticated & SecurityHelper.IsUserAuthorized(); 
    }
    

    我不明白为什么你在失败的身份验证上重定向,肯定API应该返回401?

  • 1

    我在这里想知道这段代码:

    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
    

    在某些地方,您必须使用以下内容配置OWIN层:

    var cookieAuthenticationOptions = new CookieAuthenticationOptions
        {
            LoginPath = new PathString(loginPath)
        }
    
    app.UseCookieAuthentication(cookieAuthenticationOptions);
    

    从身份验证筛选器返回401时,OWIN基础结构会自动将您重定向到您指定的任何LoginPath . 但是当试图满足该请求时,它会调用您的过滤器,但由于用户未经授权,因此返回401,导致重定向到LoginPath,依此类推,等等 .

    因为这是一个API调用,所以需要以不同的方式处理401 . 以下博客文章讨论了这种情况 .

    http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

    简而言之,在配置 CookieAuthenticationOptions 时,您需要指定自己的 Provider ,并且只有在不是AJAX请求时才指示 .

    var cookieAuthenticationOptions = new CookieAuthenticationOptions
        {
            LoginPath = new PathString(loginPath),
            Provider = new CookieAuthenticationProvider()
            {
                OnApplyRedirect = context =>
                {
                    if (!context.Request.IsAjaxRequest())
                    { context.Response.Redirect(context.RedirectUri); }
                }
            }
        }
    

相关问题