2

我用 Authorize 属性装饰了我的控制器,如下所示:

[Authorize(Roles="ExecAdmin")]

如果我在以非 ExecAdmin 用户身份登录后尝试访问该控制器,它似乎确实在尝试重定向到登录页面。但是,它试图重定向到的页面不是我的登录页面,它是一个名为 LogOnUserControl.ascx 的视图。这是我的登录页面未显示的部分视图。

我不知道它为什么这样做——或者它可能试图完全重定向到其他页面,一个确实显示 LogOnUserControl.ascx 的页面。或者它正在寻找名称中带有“LogOn”的任何东西?(虽然我的登录视图的名称是 LogOn.aspx...)

我怎样才能告诉它重定向到哪个页面?

更新:我在 global.asax 中有这个

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie == null || authCookie.Value == "")
    {
        return;
    }
    FormsAuthenticationTicket authTicket = null;
    try
    {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch
    {
        return;
    }
    string[] roles = authTicket.UserData.Split(new char[] { ';' });
    //Context.ClearError(); 
    if (Context.User != null)
    {
        Context.User = new System.Security.Principal.GenericPrincipal(Context.User.Identity, roles);
    }
}

...因为我使用的是非标准的角色定义方式;即,我没有使用 ASP.NET 成员资格方案(在 web.config 等中定义了角色提供程序)。相反,我以这种方式设置角色:

// get user's role
string role = rc.rolesRepository.GetUserType(rc.loginRepository.GetUserID(userName)).ToString();

// create encryption cookie
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
        1,
        userName,
        DateTime.Now,
        DateTime.Now.AddMinutes(120),
        createPersistentCookie,
        role //user's role 
        );

// add cookie to response stream
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

System.Web.HttpCookie authCookie = new System.Web.HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);

(这在用户被验证后调用。)

不知道这会如何影响整个事情,虽然......

更新:感谢罗伯特的解决方案,这就是我解决它的方法——扩展 AuthorizeAttribute 类:

public class AuthorizeAttributeWithMessage : AuthorizeAttribute
{
    private string _message = "";
    public string Message
    {
        get { 
            return _message; 
        }
        set { 
            _message = value;
        }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            // user is logged in but wrong role or user:
            filterContext.Controller.TempData.Add("Message", Message);
        }
        base.HandleUnauthorizedRequest(filterContext);
    }
}

然后在 LogOn 视图中:

<% 
    if (HttpContext.Current.Request.IsAuthenticated)
    {
        // authenticated users should not be here
        Response.Redirect("/Home/Index");
    }
%>

在主页视图中:

<% if (TempData != null && TempData.Count > 0 && TempData.ContainsKey("Message"))
   { %>
<div class="largewarningtext"><%= TempData["Message"]%></div>
<% } %>

在受影响的控制器上:

[AuthorizeAttributeWithMessage(Roles = "Consultant,ExecAdmin", Message = "You do not have access to the requested page")]

这具有始终重定向任何最终登录 Logon.aspx 的经过身份验证的用户的优势——经过身份验证的用户不应该在那里。如果 TempData 中有消息,则会在首页打印出来;如果没有,它至少会完成重定向。

4

1 回答 1

3

登录页面在web.config文件中配置。

但你可能已经知道了。这里真正的问题有点复杂。我想您在这里遇到了一些非常有趣的事情,因为登录页面几乎没有对用户进行身份验证。它不会检查其对特定资源的授权(这是您在此处授权失败的情况),因此这不应该首先重定向到登录页面。

检查AuthorizeAttribute源代码,您应该得到401: Unauthorize Request服务器的响应。它不会将您重定向到登录页面(正如我在上一段中所预期的那样,因为登录太愚蠢了。因此,您的代码中大多数其他内容无法正常工作。

编辑

本页所述:

如果站点配置为使用 ASP.NET 表单身份验证,则 401 状态代码会导致浏览器将用户重定向到登录页面。

基于此信息,它实际上形成了看到此 401 并重定向到登录的身份验证(按照您在评论中的描述进行配置)。

但。最好向用户展示为什么他们首先被重定向到登录页面的一些消息。没有内置功能......仍然这些知识并不能解决您的问题,是不是......

编辑 2

您可以采用两种模式,它们实际上看起来与用户非常相似,但在服务器上的工作方式不同。

更简单的一个

  1. 编写您自己的授权属性(只需从现有的继承并添加一个额外的公共属性Message),您还可以在其中提供某种带有属性声明的消息,例如 ie。

    [AuthorizeWithMessage(Role = "ExecAdmin", Message = "You need at least ExecAdmin permissions to access requested resource."]
    
  2. TempData您的授权属性应该使用提供的消息填充字典(检查有关我将在这种情况下使用的文档),然后调用基类功能TempData

  3. 更改您的登录视图以检查TempData字典中的消息。如果有,您可以轻松地将其呈现给已通过身份验证的用户(以及指向他们可以访问的某个主页的链接),这样他们就会知道为什么会出现登录信息。

复杂一

  1. 创建您自己的授权过滤器(不是从原始过滤器继承)并提供您自己的重定向到某个授权登录视图,以防用户权限不足时为登录提供服务。

  2. 创建您的自定义登录视图,在这种情况下可以是强类型。您的授权过滤器可以使用正确的模型填充它。该模型将包含消息字符串,它还可以提供指向用户可以访问的页面的路由链接。

  3. 为自定义登录页面的此配置提供服务的自定义配置类。

您也可以根据用户权限配置各种不同的路由定义。因此,对于某些权限,他们会看到一些页面,但如果他们有其他权限,他们的路线将指向不同的路线。

选择哪一个?

如果满足您的需求,请选择更简单的,但如果您想更好地控制整个过程,我宁愿选择复杂的。它并没有那么复杂,它可以让您完全控制不充分的登录过程。您可以为用户提供更好的体验。

于 2010-08-03T21:56:54.213 回答