3

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

我已经覆盖了 OnAuthorization 方法。在这种方法中,我检查用户是否经过身份验证。如果未通过身份验证,我会挑战用户登录。

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

我看到的问题是这样的:在用户成功验证但未能获得授权后,我看到有一个无限循环重定向到登录页面。

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

* 用片段更新 *

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);
    }
}
4

2 回答 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 吗?

于 2015-04-01T11:15:02.183 回答
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); }
            }
        }
    }
于 2015-03-31T18:17:09.780 回答