如何覆盖某些网页的身份验证....?

时间:2011-05-04 17:52:14

标签: c# .net asp.net authentication forms-authentication

我正在使用母版页编写以下代码: -

<authentication mode="Forms">
    <forms loginUrl="Loginpage.aspx" />
</authentication>

现在,如果身份验证失败,它将重定向到“Loginpage.aspx”。

现在如果我想覆盖几页的身份验证。另请注意,页面和页面名称的数量在设计时不可用,因此不能在配置文件中包含aspx页面名称。

无论如何都要覆盖少数aspx页面的身份验证吗?

-Anil

3 个答案:

答案 0 :(得分:3)

Henrik的答案很好,如果实施得当,应该可以正常运作。但是,这是从配置角度更多地解决问题的另一种选择。我知道你提到你不会提前知道页面名称,所以你不能在每个页面的web.config中包含一个条目但是web.config也允许你保护文件夹。例如,您可以将需要身份验证的所有页面放在名为“AuthRequired”的文件夹中,将所有不需要身份验证的页面放在名为“匿名”的文件夹中。然后在您的Web配置中,您可以输入以下条目:

<location path="AuthRequired">
  <system.web>
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
  </system.web>
</location>
<location path="Anonymous">
  <system.web>
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>
</location>

答案 1 :(得分:1)

您可以收听AuthorizeRequest事件并采取相应措施。创建自己的Http模块来执行此操作。

三个选项:

  • 使用上面的配置设置以及使用web.config条目生成文件夹。这是一种非常粗制滥造的方式。

  • 收听AuthenticateRequest事件,代码如下:

    public class UserAuthenticationModule : IHttpModule
    {
    private HttpApplication _Context;
    private RoleManagerModule _RoleManager;
    
    public void Init(HttpApplication context)
    {
        _Context = context;
        context.AuthenticateRequest += AuthenticateUser;
        _RoleManager = (RoleManagerModule)context.Modules["RoleManager"];
        _RoleManager.GetRoles += roleManager_GetRoles;
    }
    
    // http://stackoverflow.com/questions/1727960/how-to-keep-roleprovider-from-overriding-custom-roles
    private void roleManager_GetRoles(object sender, RoleManagerEventArgs e)
    {
        if (_Context.User is UserPrincipal)
            e.RolesPopulated = true; // allows roles set in AuthenticateUser to stick.
    }
    
    private static void AuthenticateUser(object sender, EventArgs e)
    {
        var app = (HttpApplication) sender;
        if (app.Context == null) return;
    
        var user = app.Context.User;
    
        // not signed in, forms authentication module takes care of redirecting etc.
        if (user == null) return;
        // we're done then.
        if (user is IUser) return;
    
        var userEntity = IoC.Resolve<IUserRepository>().FindByUserName(user.Identity.Name);
    
        // we can't find the user in the database.
        if (userEntity == null)
            throw new ApplicationException(string.Format("User \"{0}\" deleted from, or renamed in, database while logged into application.", 
                user.Identity.Name));
    
        // signed in, assigning user, which should assign Thread.CurrentPrincipal as well (it wouldn't do this on PostAuthenticateRequest).
        app.Context.User = new UserPrincipal(userEntity);
        userEntity.SetAuthenticated();
    }
    
    //Implement IDisposable.
    public void Dispose()
    {
    }
    }
    

如果您的UserPrincipal实现了IPrincipal,则使用IsInRole为您的网页提供基于角色的访问。

  • 以服务为导向的方式;设置一个小的透明代理服务器。在动态商店中列出您的端点/ uri-s,就像您所描述的那样。设置授权服务,如Rhino Security;将其服务接口公开为REST-API或请求/回复接口等。从Web应用程序的角度假设允许每个请求并处理您重定向的位置。在代理服务器中,例如nginx是Linux上一个非常好的异步基于C的代理服务器,从过滤器/模块调用您的授权服务。 “深入安全”,您可以在授权服务中共享安全性配置。

您遵循的原则是,如果Web应用程序中不允许某些内容,您可以在AuthorizeRequest事件中执行throw new HttpException(405, "The current operation you are trying to perform is now allowed for your role or user or chosen path in life")请注意,有一个AuthenticateRequest和另一个AuthorizeRequest事件

答案 2 :(得分:0)

您通常应该一个点,用户可以进行身份验证 - 确认他们是他们声称的人。接下来,您可能正在谈论授权,这是允许/拒绝向用户执行某些操作的问题,例如发送GET请求。可以通过 location 元素在web.config中配置简单方案中的授权规则,如Tom所示。