2010-07-21 107 views
3

所以,我实现了我的IPrincipal.IsInRole(...),我使用FormsAuthentication像这样:授权被拒绝的消息与FormsAuthentication

<authentication mode="Forms"> 
    <forms loginUrl="Login.aspx" name="someName" timeout="600"/> 
</authentication> 

然后我就被验证,需要你的网页并且你有“角色A”。这种配置,像这样:

<location path="SomePage.aspx"> 
    <system.web> 
    <authorization> 
    <allow roles="roleA" /> 
    <deny users="*"/> 
    </authorization> 
    </system.web> 
</location> 

现在,我登录到我的web应用程序,但不具有roleA用户。当我访问SomePage.aspx时,我被重定向到Login.aspx,这是在forms元素的loginUrl中指定的url。所以,我的问题是我不应该能够指定授权被拒绝的消息或网址?如果用户已通过身份验证,但未获得授权,我为什么要重定向到登录页面。这对用户来说太麻烦了。请告诉我,我错过了一些简单的事情。

感谢您的阅读!

回答

1

是的,这有点烦人。也许有人有一个更简单的想法,但我们提出的解决方案(黑客?)是查找当用户重定向到登录页面时ASP.NET附加到查询字符串的最初请求的URL。

我们创建了存储一组密钥的重定向URL的片段匹配到授权消息/值的新的web.config部分:

<configSections> 
    <section name="authorizationFailureMessages" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    ...etc... 
</configSections> 

<authorizationFailureMessages> 
    <add key="MemberResources" value="MembershipRequired" /> 
    <add key="Staff" value="StaffOnly" /> 
    <add key="Departments/Administration/BoardOfDirectors" value="BoardOfDirectorsOnly" /> 
    ...etc... 
</authorizationFailureMessages> 

在登录的的Page_Load()事件。 aspx页面,我们称使用该URL来确定方法,(联合国)授权事件发生然后将其重定向到显示相应的文本消息页:

private void DisplayAppropriateAuthorizationMessage() 
{ 
    if (!Page.User.Identity.IsAuthenticated) 
     return; 

    string redirectUrl = FormsAuthentication.GetRedirectUrl(Page.User.Identity.Name, false); 

    if (string.IsNullOrEmpty(redirectUrl)) 
     return; 

    NameValueCollection authorizationFailureMessages = ConfigurationManager.GetSection("authorizationFailureMessages") as NameValueCollection; 

    if (authorizationFailureMessages == null) 
     return; 

    foreach (string key in authorizationFailureMessages.AllKeys) 
    { 
     if (redirectUrl.Contains(key)) 
     { 
      Response.Redirect(String.Format("Message.aspx?{0}={1}", Constants.QueryStringKeys.ERRORMESSAGENAME, authorizationFailureMessages[ key ]), true); 
     } 
    } 
} 
+0

呃,这必须是正确的答案,因为我希望我不会诉诸这样的东西:(虽然这有帮助,但我觉得有点愚蠢,非常感谢! – 2010-07-21 15:33:24

+0

我是仍然抱着别人想出更聪明的希望:)当然,理想的解决方案是如果ASP.NET暴露(例如,在Request对象上)引用导致授权失败的特定角色。 – 2010-07-21 15:41:06

+0

这不会显示授权的用户未经授权的消息,但只是没有登录,并试图击中该URL? – Chris 2013-07-23 16:00:27

1

Roles.IsUserInRole - 如果你只是使用它为这个页面,把它放在后面的代码中。如果你有很多页面,你可以考虑把它放在一个基类中,然后从web.config或者每个页面读取数据库。我相信这会给你最大的控制力。

0

我基本上同意@MattPeterson的解决方案。但我建议两个改进。

  1. 在我看来,你只是告诉“根据你的角色,你不允许访问该页面”,这就够了。您不需要知道哪些额外的角色是必需的,哪些会暴露您的网站授权管理的细节。

  2. 您可以从web.config(在每个文件夹中)获得访问控制列表,并且无需再次编写<add key="MemberResources" value="MembershipRequired" />

我相信你应该在你的web.config有类似的东西

<authorization> 
    <deny users="?" /> 
</authorization