基于安全组的身份验证

时间:2014-04-28 06:09:03

标签: c# asp.net security authentication

我正在尝试根据数据库中存在的安全组对用户进行身份验证。

我在System.Web.Security.Users.IsUserInRole(string rolename)内使用Page_Load()

即使用户是安全组的一部分,用户也不会进行身份验证。

我不知道我哪里错了。我在roleManager中启用了web.config

代码的每次迭代都会打印“用户未经过身份验证”。

我正在尝试从我的本地计算机访问此代码,该计算机是客户端企业网络的一部分,安全组也存在。

PFB代码:

WebForm1.aspx.cs

SqlConnection xconn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectToDB"].ToString());
protected void Page_Load(object sender, EventArgs e)
{
    DataTable dt = getData();
    string securityGroup = dt.Rows[0][1].ToString();//**securityGroup=Redmond\\myTeam**
    if (System.Web.Security.Roles.IsUserInRole(securityGroup))
    {
        Response.Write("User is authenticated");
    }
    else
    {
        Response.Write("User is not authenticated");
    }
}
public DataTable getData()
{
    SqlDataAdapter da = new SqlDataAdapter("select * from Sample.dbo.ReportConfig", xconn);
    DataTable dt = new DataTable();
    da.Fill(dt);
    return dt;
}

Web.Config

<configuration>
    <system.web>
      <roleManager enabled="true" defaultProvider="Default">
        <providers>
          <add name="Default" type="System.Web.Security.WindowsTokenRoleProvider"/>
        </providers>
      </roleManager>
      <compilation debug="true" targetFramework="4.0" />
    </system.web>
  <connectionStrings>
    <add name="ConnectToDB" connectionString="Data Source=Dev-PC;Initial Catalog=Sample;Integrated Security=SSPI" providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>

任何指针都会非常感激。

1 个答案:

答案 0 :(得分:0)

默认情况下,您无法使用System.Web.Security.Roles.IsUserInRole来检查AD组。此方法在默认配置中检查成员资格数据库。解决这个问题的一种方法是,我在成功的应用程序中使用了它:

在登录时将每个AD用户的组复制​​到成员资格数据库。这当然有缺点,只有在用户登录时才会检测到角色更改:

var user = model.UserName.Split('\\');
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, user[0]))
{
    if (pc.ValidateCredentials(user[1], model.Password, ContextOptions.Negotiate))
    {
        using (var adUser = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, user[1]))
        {
            if (!MembershipService.ValidateUser(model.UserName, model.Password))
            {
                using (var _userDb = new UsersDbContext())
                {
                    if (_userDb.aspnet_Users.Count(u => u.UserName.ToLower().Contains(model.UserName)) <= 0)
                    {
                        MembershipService.CreateUser(model.UserName, model.Password, adUser.EmailAddress);
                    }
                    else
                    {
                        var msUser = Membership.GetUser(model.UserName);
                        msUser.ChangePassword(msUser.ResetPassword(), model.Password);
                    }
                }
            }
            FormsService.SignIn(model.UserName, model.RememberMe);

            foreach (var role in Roles.GetAllRoles())
            {
                if (role == LoginRoles.Customer)
                    continue;

                using (var group = GroupPrincipal.FindByIdentity(pc, role))
                {
                    if (group != null)
                    {
                        if (adUser.IsMemberOf(group))
                        {
                            if (!Roles.IsUserInRole(model.UserName, role))
                                Roles.AddUserToRole(model.UserName, role);
                        }
                        else
                        {
                            if (Roles.IsUserInRole(model.UserName, role))
                                Roles.RemoveUserFromRole(model.UserName, role);
                        }
                    }
                }
            }
        }
    }
}

在我的情况下,AD中的组已经存在于会员DB中。如果它们不在你的情况下,你也需要创建或同步它们。

另一种方法是创建自己的角色提供程序,在每次调用时查询AD(可能已经存在一个)。我使用了上面的方法,因为我有混合用户,其中只有一些用户来自应用程序,也是AD成员。我使用\来区分它们。一旦用户使用例如用户登录DOMAIN\user而不只是user我使用上述代码查询AD。