判断用户是否对路径拥有访问权限,Windows身份认
分类:计算机编程

何以收获当前系统客商对文本/文件夹的操作权限?

细说ASP.NET Windows身份认证

开卷目录

  • 开始
  • 认知ASP.NET Windows身份申明
  • 访问 Active Directory
  • 在ASP.NET中访问Active Directory
  • 动用Active Directory验证客商地方
  • 康宁上下文与客户模拟
  • 在IIS中布署Windows身份验证
  • 关于浏览器的报到对话框难点
  • 在客商端代码中访谈Windows身份ID明的页面

上篇博客自家聊到了某个有关ASP.NET Forms身份认证方面包车型大巴话题,此次的博客将重大介绍ASP.NET Windows身份验证。

Forms居民身份表明即使使用大范围,不过,若是是在 Windows Active Directory 的条件中行使ASP.NET, 那么使用Windows身份认证也会相比有利。 方便性表现为:大家毫不再规划登陆页面,不用编写登入验证逻辑。而且采取Windows身份认证会有更加好的四平保险。

回来最上端

上篇博客自家谈起了有些有关ASP.NET Forms身份认证方面包车型大巴话题,此番的博客将第一介绍ASP.NET Windows居民身份注解。

 1.到手安全新闻DirectorySecurity

DirectorySecurity fileAcl = Directory.GetAccessControl(folder);

通过Directory.GetAccessControl获取文件夹的权位/安全消息

详见介绍,可仿效MSDN官方文书档案)

对文本/文件夹权限的亲力亲为操作,可参照大器晚成篇博客C#文件夹权限操作

认识ASP.NET Windows身份认证

要动用Windows身份认证情势,须要在web.config设置:

<authentication mode="Windows" />

Windows身份认证做为ASP.NET的默许认证格局,与Forms身份ID明在众多基础方面是意气风发律的。上篇博客我说过:自己感到ASP.NET的地点申明的最中央部分其实就是HttpContext.User这几个本性所针对的靶子。在接下去的大器晚成对,笔者将重大剖判这一个指标在三种身份ID明中有啥样差异。

在ASP.NET身份认证进度中,IPrincipal和IIdentity那几个接口有着比较重大的功用。 前边三个定义客户对象的基本功用,前者定义标志对象的基本作用, 差异的身份ID明方法赢得的那二个接口的实例也是莫衷一是的。

ASP.NET Windows身份验证是由WindowsAuthenticationModule达成的。WindowsAuthenticationModule在ASP.NET管线的AuthenticateRequest事件中, 使用从IIS传递到ASP.NET的Windows访问令牌(Token)创建一个WindowsIdentity对象,Token通过调用context.WorkerRequest.GetUserToken()获得, 然后再依照WindowsIdentity 对象创立WindowsPrincipal对象, 然后把它赋值给HttpContext.User。

在Forms身份认证中,我们须求创设登陆页面,让顾客提交顾客名和密码,然后检查客户名和密码的不易, 接下来创立七个饱含FormsAuthenticationTicket对象的登录库克ie供后续央求使用。FormsAuthenticationModule在ASP.NET管线的AuthenticateRequest事件中, 剖析登入Cookie并创办八个带有FormsIdentity的GenericPrincipal对象, 然后把它赋值给HttpContext.User。

地点二段话归纳了归纳了三种身份申明方法的职业措施。 大家得以窥见它们存在以下差距: 1. Forms地位认证须要Cookie表示登入状态,Windows身份ID明则依附于IIS 2. Windows身份验证不要求大家两全登陆页面,不用编写登陆验证逻辑,因而更便于采纳。

在授权阶段,UrlAuthorizationModule还是会依照近来客户检查将要访谈的财富是或不是获得许可。 接下来,FileAuthorizationModule检查 HttpContext.User.Identity 属性中的 IIdentity 对象是或不是是 WindowsIdentity 类的贰个实例。 假若 IIdentity 对象不是 WindowsIdentity 类的二个实例,则 FileAuthorizationModule 类截至管理。 借使存在 WindowsIdentity 类的三个实例,则 FileAuthorizationModule 类调用 AccessCheck Win32 函数(通过 P/Invoke) 来鲜明是否授权经过身份验证的顾客端访谈伏乞的公文。 假若该文件的平安描述符的率性访问调控列表 (DACL) 中起码含有二个 Read 访问调节项 (ACE),则允许该必要继续。 不然,FileAuthorizationModule 类调用 HttpApplication.CompleteRequest 方法并将状态码 401 重临到客商端。

在Windows身份验证中,验证专门的学问关键是由IIS完成的,WindowsAuthenticationModule其实只是背负创设WindowsPrincipal和WindowsIdentity而已。 顺便介绍一下:Windows 身份验证又分为“NTLM 身份验证”和“Kerberos v5 身份验证”二种, 关于那二种Windows身份认证的越多表明可查看MSDN本领小说:解释:ASP.NET 2.0 中的 Windows 身份验证。 以作者之见,IIS最后利用哪个种类Windows身份认证格局并不影响大家的支付进程,由此本文不会商讨这几个话题。

听别人说本身的其实经历来看,使用Windows身份验证时,首要的支出专业将是依靠登入名从Active Directory获取客商音信。 因为,那时候没有必要大家再规划登陆进程,IIS与ASP.NET已经为大家打算好了WindowsPrincipal和WindowsIdentity那叁个与顾客身份相关的靶子。

重临最上部

Forms身份验证尽管应用大范围,不过,倘使是在 Windows Active Directory 的意况中利用ASP.NET, 那么使用Windows居民身份申明也会相比方便。 方便性展现为:大家绝不再规划登陆页面,不用编写登入验证逻辑。而且动用Windows身份ID明会有越来越好的安全保持。

2. 获得文件夹访谈权限列表FileSystemAccessRule

var rules = fileAcl.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)).OfType<FileSystemAccessRule>().ToList();

GetAccessRules()方法重临的是AuthorizationRule会集,此处只须要获得文件权限。

FileSystemAccessRule.aspx)传承自AuthorizationRule,并新添俩个属性

  • AccessControlType -- 枚举 Allow/Deny
  • FileSystemRights -- 对文件的拜望权限详细新闻(读/写等),可以知道下边列表: 

图片 1图片 2

 1   /// <summary>定义要创建访问和审核规则时使用的访问权限。</summary>
 2   [Flags]
 3   public enum FileSystemRights
 4   {
 5     ReadData = 1,
 6     ListDirectory = ReadData, // 0x00000001
 7     WriteData = 2,
 8     CreateFiles = WriteData, // 0x00000002
 9     AppendData = 4,
10     CreateDirectories = AppendData, // 0x00000004
11     ReadExtendedAttributes = 8,
12     WriteExtendedAttributes = 16, // 0x00000010
13     ExecuteFile = 32, // 0x00000020
14     Traverse = ExecuteFile, // 0x00000020
15     DeleteSubdirectoriesAndFiles = 64, // 0x00000040
16     ReadAttributes = 128, // 0x00000080
17     WriteAttributes = 256, // 0x00000100
18     Delete = 65536, // 0x00010000
19     ReadPermissions = 131072, // 0x00020000
20     ChangePermissions = 262144, // 0x00040000
21     TakeOwnership = 524288, // 0x00080000
22     Synchronize = 1048576, // 0x00100000
23     FullControl = Synchronize | TakeOwnership | ChangePermissions | ReadPermissions | Delete | WriteAttributes | ReadAttributes | DeleteSubdirectoriesAndFiles | Traverse | WriteExtendedAttributes | ReadExtendedAttributes | CreateDirectories | CreateFiles | ListDirectory, // 0x001F01FF
24     Read = ReadPermissions | ReadAttributes | ReadExtendedAttributes | ListDirectory, // 0x00020089
25     ReadAndExecute = Read | Traverse, // 0x000200A9
26     Write = WriteAttributes | WriteExtendedAttributes | CreateDirectories | CreateFiles, // 0x00000116
27     Modify = Write | ReadAndExecute | Delete, // 0x000301BF
28   }

View Code

 因为AuthorizationRule中,IdentityReference对应权限的客商/顾客组标志,格式为:"MYDOMAINMyAccount"

就此,如通过当前系统客户名与IdentityReference相配,就能够猎取FileSystemAccessRule权限。怎样赢得客户名,见下大器晚成段落

访问 Active Directory

大家比比皆已选取LDAP左券来访问Active Directory, 在.net framework中提供了DirectoryEntry和DirectorySearcher那二个品种让大家得以方便地从托管代码中拜访Active Directory 域服务。

万后生可畏大家要在"test.corp”那些域中搜索某些客商音信,大家得以行使上边包车型地铁语句构造三个DirectoryEntry对象:

DirectoryEntry entry = new DirectoryEntry("LDAP://test.corp");

在这里段代码中,笔者动用硬编码的艺术把域名写进了代码。 大家什么领悟当前Computer所利用的是哪位域名呢? 答案是:查看“作者的微机”的本性对话框:

图片 3

注意:那么些域名不必然与System.Environment.UserDomainName相仿。

除去能够查阅“作者的计算机”的性质对话框外,大家仍是可以动用代码的艺术获得当前Computer所选拔的域名:

private static string GetDomainName()
{
    // 注意:这段代码需要在Windows XP及较新版本的操作系统中才能正常运行。
    SelectQuery query = new SelectQuery("Win32_ComputerSystem");
    using( ManagementObjectSearcher searcher = new ManagementObjectSearcher(query) ) {
        foreach( ManagementObject mo in searcher.Get() ) {
            if( (bool)mo["partofdomain"] )
                return mo["domain"].ToString();
        }
    }
    return null;
}

当组织了DirectorySearcher对象后,我们便可以行使DirectorySearcher来施行对Active Directory的找出。 我们能够动用上边包车型客车步子来实践找出: 1. 设置 DirectorySearcher.Filter 提醒LDAP格式筛选器,那是二个字符串。 2. 一再调用PropertiesToLoad.Add() 设置找寻进度中要探求的特性列表。 3. 调用FindOne() 方法获得找寻结果。

上边包车型客车代码演示了什么样从Active Directory中查究登入名称叫“fl45”的客商音讯:

static void Main(string[] args)
{
    Console.WriteLine(Environment.UserDomainName);
    Console.WriteLine(Environment.UserName);
    Console.WriteLine("------------------------------------------------");

    ShowUserInfo("fl45", GetDomainName());
}

private static string AllProperties = "name,givenName,samaccountname,mail";

public static void ShowUserInfo(string loginName, string domainName)
{
    if( string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(domainName) )
        return;

    string[] properties = AllProperties.Split(new char[] { 'r', 'n', ',' }, 
                        StringSplitOptions.RemoveEmptyEntries);

    try {
        DirectoryEntry entry = new DirectoryEntry("LDAP://"   domainName);
        DirectorySearcher search = new DirectorySearcher(entry);
        search.Filter = "(samaccountname="   loginName   ")";

        foreach( string p in properties )
            search.PropertiesToLoad.Add(p);

        SearchResult result = search.FindOne();

        if( result != null ) {
            foreach( string p in properties ) {
                ResultPropertyValueCollection collection = result.Properties[p];
                for( int i = 0; i < collection.Count; i   )
                    Console.WriteLine(p   ": "   collection[i]);
            }
        }
    }
    catch( Exception ex ) {
        Console.WriteLine(ex.ToString());
    }
}

结果如下:

图片 4

在日前的代码,小编在找寻Active Directory时,只寻觅了"name,givenName,samaccountname,mail"那4个性子。 可是,LDAP还支持更加多的性子,大家得以应用上边包车型大巴代码查看更加多的顾客新闻:图片 5;)

        private static string AllProperties = @"
homemdb
distinguishedname
countrycode
cn
lastlogoff
mailnickname
dscorepropagationdata
msexchhomeservername
msexchmailboxsecuritydescriptor
msexchalobjectversion
usncreated
objectguid
whenchanged
memberof
msexchuseraccountcontrol
accountexpires
displayname
primarygroupid
badpwdcount
objectclass
instancetype
objectcategory
samaccounttype
whencreated
lastlogon
useraccountcontrol
physicaldeliveryofficename
samaccountname
usercertificate
givenname
mail
userparameters
adspath
homemta
msexchmailboxguid
pwdlastset
logoncount
codepage
name
usnchanged
legacyexchangedn
proxyaddresses
department
userprincipalname
badpasswordtime
objectsid
sn
mdbusedefaults
telephonenumber
showinaddressbook
msexchpoliciesincluded
textencodedoraddress
lastlogontimestamp
company
";

回来顶上部分

回去顶端

3. 取安妥前系统客户名/顾客组

因而 System.Environment.UserDomainName 和 System.Environment.UserName 取妥善前用户名

对近期系统客商名/客商组的此外操作,可参照

  • C# 管理 Windows 本地顾客组
  • C# 获取 Windows 客户组成员

由此,将Path.Combine(Environment.UserDomainName, Environment.UserName)与IdentityReference.Value相比较,获取当前客户对文本夹的权位音信

详细达成如下:

 1     /// <summary>
 2     /// 检查当前用户是否拥有此文件夹的操作权限
 3     /// </summary>
 4     /// <param name="folder"></param>
 5     /// <returns></returns>
 6     public static bool HasOperationPermission(string folder)
 7     {
 8         var currentUserIdentity = Path.Combine(Environment.UserDomainName, Environment.UserName);
 9 
10         DirectorySecurity fileAcl = Directory.GetAccessControl(folder);
11         var userAccessRules = fileAcl.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)).OfType<FileSystemAccessRule>().Where(i=>i.IdentityReference.Value==currentUserIdentity).ToList();
12 
13         return userAccessRules.Any(i => i.AccessControlType == AccessControlType.Deny);
14     }

 

在ASP.NET中访问Active Directory

眼下作者在三个调控台程序中示范了拜见Active Directory的格局,通过演示大家得以看看:在代码中,作者用Environment.UserName就能够获得当前客户的登陆名。 但是,假若是在ASP.NET程序中,访谈Environment.UserName就很有望得不到确实顾客登入名。 因为:Environment.UserName是应用WIN32API中的GetUserName获取线程相关的顾客名,但ASP.NET运维在IIS中,线程相关的顾客名就不自然是客商端的客商名了。 不过,ASP.NET可以效仿顾客格局运转,通过这种艺术才足以拿走不错的结果。关于“模拟”的话题在本文的后面部分有表达。

在ASP.NET中,为了能可相信的获取登陆客户的登陆名,大家可以动用上边包车型地铁代码:

/// <summary>
/// 根据指定的HttpContext对象,获取登录名。
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetUserLoginName(HttpContext context)
{
    if( context == null )
        return null;

    if( context.Request.IsAuthenticated == false )
        return null;

    string userName = context.User.Identity.Name;
    // 此时userName的格式为:UserDomainNameLoginName
    // 我们只需要后面的LoginName就可以了。

    string[] array = userName.Split(new char[] { '\' }, StringSplitOptions.RemoveEmptyEntries);
    if( array.Length == 2 )
        return array[1];

    return null;
}

在ASP.NET中运用Windows身份认证时,IIS和WindowsAuthenticationModule已经做了重重认证顾客的连锁工作, 即便大家得以采取前边的代码获取到顾客的登陆名,但客户的别的新闻即要求大家团结来赢得。 在实质上接受Windows身份ID明时,我们要做的事:基本上就是从Active Directory中依据顾客的登陆名获得所需的各样音信。

举例说:笔者的先后在运营时,还亟需接收以下与客户相关的新闻:

public sealed class UserInfo
{
    public string GivenName;
    public string FullName;
    public string Email;
}

那么,大家能够运用那样的代码来获得所需的顾客音信:图片 6;)

public static class UserHelper
{
    /// <summary>
    /// 活动目录中的搜索路径,也可根据实际情况来修改这个值。
    /// </summary>
    public static string DirectoryPath = "LDAP://"   GetDomainName();


    /// <summary>
    /// 获取与指定HttpContext相关的用户信息
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static UserInfo GetCurrentUserInfo(HttpContext context)
    {
        string loginName = GetUserLoginName(context);
        if( string.IsNullOrEmpty(loginName) )
            return null;

        return GetUserInfoByLoginName(loginName);
    }

    /// <summary>
    /// 根据指定的HttpContext对象,获取登录名。
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static string GetUserLoginName(HttpContext context)
    {
        if( context == null )
            return null;

        if( context.Request.IsAuthenticated == false )
            return null;

        string userName = context.User.Identity.Name;
        // 此时userName的格式为:UserDomainNameLoginName
        // 我们只需要后面的LoginName就可以了。

        string[] array = userName.Split(new char[] { '\' }, StringSplitOptions.RemoveEmptyEntries);
        if( array.Length == 2 )
            return array[1];

        return null;
    }


    /// <summary>
    /// 根据登录名查询活动目录,获取用户信息。
    /// </summary>
    /// <param name="loginName"></param>
    /// <returns></returns>
    public static UserInfo GetUserInfoByLoginName(string loginName)
    {
        if( string.IsNullOrEmpty(loginName) )
            return null;

        // 下面的代码将根据登录名查询用户在AD中的信息。
        // 为了提高性能,可以在此处增加一个缓存容器(Dictionary or Hashtable)。

        try {
            DirectoryEntry entry = new DirectoryEntry(DirectoryPath);
            DirectorySearcher search = new DirectorySearcher(entry);
            search.Filter = "(SAMAccountName="   loginName   ")";

            search.PropertiesToLoad.Add("givenName");
            search.PropertiesToLoad.Add("cn");
            search.PropertiesToLoad.Add("mail");
            // 如果还需要从AD中获取其它的用户信息,请参考ActiveDirectoryDEMO

            SearchResult result = search.FindOne();

            if( result != null ) {
                UserInfo info = new UserInfo();
                info.GivenName = result.Properties["givenName"][0].ToString();
                info.FullName = result.Properties["cn"][0].ToString();
                info.Email = result.Properties["mail"][0].ToString();
                return info;
            }
        }
        catch {
            // 如果需要记录异常,请在此处添加代码。
        }
        return null;
    }


    private static string GetDomainName()
    {
        // 注意:这段代码需要在Windows XP及较新版本的操作系统中才能正常运行。
        SelectQuery query = new SelectQuery("Win32_ComputerSystem");
        using( ManagementObjectSearcher searcher = new ManagementObjectSearcher(query) ) {
            foreach( ManagementObject mo in searcher.Get() ) {
                if( (bool)mo["partofdomain"] )
                    return mo["domain"].ToString();
            }
        }
        return null;
    }

}

接受UserHelper的页面代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WindowsAuthentication DEMO  - http://www.cnblogs.com/fish-li/</title>
</head>
<body>
<% if( Request.IsAuthenticated ) { %>
    当前登录全名:<%= Context.User.Identity.Name.HtmlEncode()%> <br />

    <% var user = UserHelper.GetCurrentUserInfo(Context); %>
    <% if( user != null ) { %>
        用户短名:<%= user.GivenName.HtmlEncode()%> <br />
        用户全名:<%= user.FullName.HtmlEncode() %> <br />
        邮箱地址:<%= user.Email.HtmlEncode() %>
    <% } %>    
<% } else { %>
    当前用户还未登录。
<% } %>
</body>
</html>

程序运转的功能如下:

图片 7

此外,还是能从Active Directory查询多少个称呼memberof的天性(它与Windows客商组非亲非故),有的时候候能够用它有别于客户,设计与权力相关的操作。

在规划数据漫长化的表结构时,由于此风尚无“客商表”,那么咱们能够直接保存客商的登陆名。 剩下的费用职业就与Forms居民身份申明未有太多的差距了。

回去顶上部分

认知ASP.NET Windows身份认证

要利用Windows身份认证情势,需求在web.config设置:

<authentication mode="Windows" />

Windows身份认证做为ASP.NET的暗中认可认证方法,与Forms身份ID明在众多基础方面是平等的。 上篇博客我说过:自己觉着ASP.NET的地位注脚的最中央部分其实就是HttpContext.User那性情情所指向的指标。 在接下去的有个别,我将重大剖析这些指标在三种居民身份声明中有何样差别。

在ASP.NET身份认证进度中,IPrincipal和IIdentity那一个接口有着特别首要的功用。 前面二个定义客户对象的基本成效,前者定义标志对象的基本功效, 不一致的身价认证方法赢得的这三个接口的实例也是差别的。

ASP.NET Windows居民身份证明是由WindowsAuthenticationModule已毕的。 WindowsAuthenticationModule在ASP.NET管线的AuthenticateRequest事件中, 使用从IIS传递到ASP.NET的Windows访谈令牌(Token)成立八个WindowsIdentity对象,Token通过调用context.WorkerRequest.GetUserToken()获得, 然后再借助WindowsIdentity 对象成立WindowsPrincipal对象, 然后把它赋值给HttpContext.User。

在Forms身份认证中,大家须要创立登入页面,让顾客提交客户名和密码,然后检查客户名和密码的不易, 接下来创制二个包括FormsAuthenticationTicket对象的登陆库克ie供后续央浼使用。 FormsAuthenticationModule在ASP.NET管线的AuthenticateRequest事件中, 剖析登陆Cookie并创立一个带有FormsIdentity的GenericPrincipal对象, 然后把它赋值给HttpContext.User。

上边二段话回顾了席卷了二种身份验证方法的行事章程。
笔者们能够发掘它们存在以下差异:

  1. Forms身份验证必要Cookie表示登入景况,Windows身份认证则依赖于IIS
    2. Windows身份ID明无需大家两全登陆页面,不用编写登陆验证逻辑,因而更便于选取。

在授权阶段,UrlAuthorizationModule照旧会依靠当前客商检查将在访谈的财富是还是不是获得许可。 接下来,FileAuthorizationModule检查 HttpContext.User.Identity 属性中的 IIdentity 对象是不是是 WindowsIdentity 类的一个实例。 假若 IIdentity 对象不是 WindowsIdentity 类的一个实例,则 FileAuthorizationModule 类甘休管理。 若是存在 WindowsIdentity 类的叁个实例,则 FileAuthorizationModule 类调用 AccessCheck Win32 函数(通过 P/Invoke) 来分明是或不是授权经过身份验证的顾客端访谈央求的文本。 假使该公文的来宾描述符的率性访谈调控列表 (DACL) 中最少含有三个 Read 访谈调整项 (ACE),则允许该须求继续。 不然,FileAuthorizationModule 类调用 HttpApplication.CompleteRequest 方法并将气象码 401 再次回到到顾客端。

在Windows身份认证中,验证工作首即使由IIS完毕的,WindowsAuthenticationModule其实只是担负成立WindowsPrincipal和WindowsIdentity而已。 顺便介绍一下:Windows 身份验证又分为“NTLM 身份验证”和“Kerberos v5 身份验证”三种, 关于那二种Windows居民身份注脚的越来越多表达可查看MSDN技巧小说:演说:ASP.NET 2.0 中的 Windows 身份验证。 以作者之见,IIS最后采纳哪一类Windows居民身份表明方法并不影响我们的支付进度,因而本文不议和论那个话题。

基于自身的实在经验来看,使用Windows身份验证时,主要的付出工作将是基于登入名从Active Directory获取客商音信。 因为,那时无需大家再规划登陆进度,IIS与ASP.NET已经为我们筹划好了WindowsPrincipal和WindowsIdentity这么些与顾客地点相关的对象。

回到最上部

行使Active Directory验证客商身份

前方介绍了ASP.NET Windows身份验证,在此种办法下,IIS和WindowsAuthenticationModule为我们落到实处了客商地点注解的历程。 可是,有的时候大概鉴于各个缘由,要求大家以编制程序的艺术接纳Active Directory验证客户地方,举个例子:在WinForm前后相继,恐怕其余的认证逻辑。

咱俩不光能够从Active Directory中查询顾客消息,也能够用它来落到实处认证客商身份,那样便得以完结团结的记名验证逻辑。

无论是是什么样行使Active Directory,大家都亟待运用DirectoryEntry和DirectorySearcher那一个对象。DirectoryEntry还提供多个构造函数可让大家输入顾客名和密码:

// 摘要:
//     初始化 System.DirectoryServices.DirectoryEntry 类的新实例。
//
// 参数:
//   Password:
//     在对客户端进行身份验证时使用的密码。DirectoryEntry.Password 属性初始化为该值。
//
//   username:
//     在对客户端进行身份验证时使用的用户名。DirectoryEntry.Username 属性初始化为该值。
//
//   Path:
//     此 DirectoryEntry 的路径。DirectoryEntry.Path 属性初始化为该值。
public DirectoryEntry(string path, string username, string password);

要落到实处协和的报到检查,就须要运用这几个构造函数。 以下是本人写用WinForm写的一个登入检查的演示:

private void btnLogin_Click(object sender, EventArgs e)
{
    if( txtUsername.Text.Length == 0 || txtPassword.Text.Length == 0 ) {
        MessageBox.Show("用户名或者密码不能为空。", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    string ldapPath = "LDAP://"   GetDomainName();
    string domainAndUsername = Environment.UserDomainName   "\"   txtUsername.Text;
    DirectoryEntry entry = new DirectoryEntry(ldapPath, domainAndUsername, txtPassword.Text);

    DirectorySearcher search = new DirectorySearcher(entry);

    try {
        SearchResult result = search.FindOne();

        MessageBox.Show("登录成功。", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch( Exception ex ) {
        // 如果用户名或者密码不正确,也会抛出异常。
        MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Stop);
    }
}

程序运营的效用如下:

图片 8

重回最上部

访问 Active Directory

小编们经常使用LDAP公约来访问Active Directory, 在.net framework中提供了DirectoryEntry和DirectorySearcher那三个门类让我们能够一本万利地从托管代码中访谈Active Directory 域服务。

假定我们要在"test.corp”那一个域中寻觅某些顾客音信,大家可以利用上面包车型大巴语句构造一个DirectoryEntry对象:

DirectoryEntry entry = new DirectoryEntry("LDAP://test.corp");

在这里段代码中,小编使用硬编码的法门把域名写进了代码。
我们什么精通当前计算机所选择的是哪位域名呢?
答案是:查看“小编的微型Computer”的属性对话框:

图片 9

注意:那几个域名不自然与System.Environment.UserDomainName相像。

除此之外能够查阅“小编的管理器”的品质对话框外,我们还足以行使代码的艺术得到当前Computer所利用的域名:

private static string GetDomainName()
{
    // 注意:这段代码需要在Windows XP及较新版本的操作系统中才能正常运行。
    SelectQuery query = new SelectQuery("Win32_ComputerSystem");
    using( ManagementObjectSearcher searcher = new ManagementObjectSearcher(query) ) {
        foreach( ManagementObject mo in searcher.Get() ) {
            if( (bool)mo["partofdomain"] )
                return mo["domain"].ToString();
        }
    }
    return null;
}

当组织了DirectorySearcher对象后,大家便足以利用DirectorySearcher来实践对Active Directory的搜寻。
大家得以行使上面包车型大巴步调来实行寻找:

  1. 安装 DirectorySearcher.Filter 提示LDAP格式挑选器,那是多个字符串。
  2. 再三调用PropertiesToLoad.Add() 设置寻找进度中要寻觅的性质列表。
  3. 调用FindOne() 方法赢得找寻结果。

上面包车型地铁代码演示了怎么从Active Directory中查找登陆名称为“fl45”的客商音讯:

static void Main(string[] args)
{
    Console.WriteLine(Environment.UserDomainName);
    Console.WriteLine(Environment.UserName);
    Console.WriteLine("------------------------------------------------");

    ShowUserInfo("fl45", GetDomainName());
}

private static string AllProperties = "name,givenName,samaccountname,mail";

public static void ShowUserInfo(string loginName, string domainName)
{
    if( string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(domainName) )
        return;

    string[] properties = AllProperties.Split(new char[] { 'r', 'n', ',' }, 
                        StringSplitOptions.RemoveEmptyEntries);

    try {
        DirectoryEntry entry = new DirectoryEntry("LDAP://"   domainName);
        DirectorySearcher search = new DirectorySearcher(entry);
        search.Filter = "(samaccountname="   loginName   ")";

        foreach( string p in properties )
            search.PropertiesToLoad.Add(p);

        SearchResult result = search.FindOne();

        if( result != null ) {
            foreach( string p in properties ) {
                ResultPropertyValueCollection collection = result.Properties[p];
                for( int i = 0; i < collection.Count; i   )
                    Console.WriteLine(p   ": "   collection[i]);
            }
        }
    }
    catch( Exception ex ) {
        Console.WriteLine(ex.ToString());
    }
}

结果如下:

图片 10

在前面的代码,作者在寻找Active Directory时,只搜索了"name,givenName,samaccountname,mail"那4个属性。 可是,LDAP还支持愈来愈多的习性,大家能够行使上面的代码查看越来越多的顾客信息: 图片 11

重回顶端

康宁上下文与客户模拟

在ASP.NET Windows身份认证情状中,与顾客相关的安全上下文对象保存在HttpContext.User属性中,是一个种类为WindowsPrincipal的目的, 我们还足以访问HttpContext.User.Identity来得到经过身份ID明的客商标志,它是多个WindowsIdentity类型的目的。

在.NET Framework中,大家得以经过WindowsIdentity.GetCurrent()获取与当前线程相关的WindowsIdentity对象, 这种情势赢得的是时下运作的Win32线程的平安上下文标记。 由于ASP.NET运营在IIS进度中,因而ASP.NET线程的雅安标记其实是从IIS的经过中一而再的, 所以那时用三种艺术赢得的WindowsIdentity对象实际是莫衷一是的。

在Windows操作系统中,许多权力检查都以基于Win32线程的三门峡上下文标志, 于是日前所说的二种WindowsIdentity对象会产生编制程序模型的不相符难题, 为了解决这几个标题,ASP.NET提供了“模拟”功效,同意线程以一定的Windows帐户的安全上下文来访问财富。

为了能更加好的驾驭模拟的作用,作者筹划了一个示范(ShowWindowsIdentity.ashx):

public class ShowWindowsIdentity : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        // 要观察【模拟】的影响,
        // 可以启用,禁止web.config中的设置:<identity impersonate="true"/>

        context.Response.ContentType = "text/plain";

        context.Response.Write(Environment.UserDomainName   "\"   Environment.UserName   "rn");

        WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;
        context.Response.Write(string.Format("HttpContext.Current.User.Identity: {0}, {1}rn", 
                winPrincipal.Identity.AuthenticationType, winPrincipal.Identity.Name));

        WindowsPrincipal winPrincipal2 = (WindowsPrincipal)Thread.CurrentPrincipal;
        context.Response.Write(string.Format("Thread.CurrentPrincipal.Identity: {0}, {1}rn",
                winPrincipal2.Identity.AuthenticationType, winPrincipal2.Identity.Name));

        WindowsIdentity winId = WindowsIdentity.GetCurrent();
        context.Response.Write(string.Format("WindowsIdentity.GetCurrent(): {0}, {1}",
                winId.AuthenticationType, winId.Name));
    }

首先,在web.config中设置:

<authentication mode="Windows" />

瞩目:要把网址布署在IIS中,不然看不出效果。

那个时候,访问ShowWindowsIdentity.ashx,将看到如下图所示的结果:

图片 12

当今涂改一下web.config中安装:(潜心:后边加了一句配置

<authentication mode="Windows" />
<identity impersonate="true"/>

那会儿,访谈ShowWindowsIdentity.ashx,将见到如下图所示的结果:

图片 13

表达: 1. FISH-S大切诺基V二零零一是自己的精兵简政机名。它在三个未有域的条件中。 2. fish-li是自己的多少个Windows帐号的登入名。 3. 网址安插在IIS6中,进度以NETWO卡宴K SE奥迪Q3VICE帐号运转。 4. 开发网页时,笔者输入的顾客名是fish-li

前方二张图纸的差别之处其实也正是ASP.NET的“模拟”所公布的作用。

至于模拟,笔者想说四点: 1. 在ASP.NET中,大家应有访谈HttpContext.User.Identity获取当前客商标记,那么就空头支票难点(这时得以无需效法),譬如FileAuthorizationModule便是那般管理的。 2. 仿照只是在ASP.NET应用程序访谈Windows系统能源时要求使用Windows的平安全检查查职能才会有用。

  1. Forms身份认证也能配置模拟功用,但只好模拟一个Windows帐户。 4. 多数情形下是无需效法的。

回来顶端

在ASP.NET中访问Active Directory

前方笔者在一个调节台程序中示范了会见Active Directory的办法,通过示范我们得以看看:在代码中,小编用Environment.UserName即可取稳妥前客商的登陆名。 但是,假设是在ASP.NET程序中,访谈Environment.UserName就很有望得不到确实客商登入名。 因为:Environment.UserName是利用WIN32API中的GetUserName获取线程相关的顾客名,但ASP.NET运转在IIS中,线程相关的顾客名就不自然是客商端的客户名了。 可是,ASP.NET可以如法泡制客商方式运转,通过这种措施展技能足以收获准确的结果。关于“模拟”的话题在本文的末尾部分有认证。

在ASP.NET中,为了能可相信的获取登陆顾客的登陆名,大家能够使用下边包车型大巴代码:

/// <summary>
/// 根据指定的HttpContext对象,获取登录名。
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetUserLoginName(HttpContext context)
{
    if( context == null )
        return null;

    if( context.Request.IsAuthenticated == false )
        return null;

    string userName = context.User.Identity.Name;
    // 此时userName的格式为:UserDomainNameLoginName
    // 我们只需要后面的LoginName就可以了。

    string[] array = userName.Split(new char[] { '\' }, StringSplitOptions.RemoveEmptyEntries);
    if( array.Length == 2 )
        return array[1];

    return null;
}

在ASP.NET中采纳Windows居民身份申明时,IIS和WindowsAuthenticationModule已经做了无尽验证客商的有关工作, 就算我们能够利用前边的代码获取到客户的登入名,但客户的别样消息即须要我们和谐来取得。 在骨子里运用Windows身份认证时,大家要做的事:基本上就是从Active Directory中依照客户的报到名取得所需的种种消息。

比方说:作者的次序在运营时,还需求利用以下与客户相关的新闻:

public sealed class UserInfo
{
    public string GivenName;
    public string FullName;
    public string Email;
}

那么,大家能够使用那样的代码来收获所需的客户消息: 图片 14

选用UserHelper的页面代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WindowsAuthentication DEMO  - http://www.cnblogs.com/fish-li/</title>
</head>
<body>
<% if( Request.IsAuthenticated ) { %>
    当前登录全名:<%= Context.User.Identity.Name.HtmlEncode()%> <br />

    <% var user = UserHelper.GetCurrentUserInfo(Context); %>
    <% if( user != null ) { %>
        用户短名:<%= user.GivenName.HtmlEncode()%> <br />
        用户全名:<%= user.FullName.HtmlEncode() %> <br />
        邮箱地址:<%= user.Email.HtmlEncode() %>
    <% } %>    
<% } else { %>
    当前用户还未登录。
<% } %>
</body>
</html>

程序运营的效能如下:

图片 15

此外,还是能够从Active Directory查询二个可以称作memberof的习性(它与Windows客商组非亲非故),不常候能够用它有别于顾客,设计与权力相关的操作。

在图谋数据长久化的表结构时,由于那时候不曾“顾客表”,那么大家能够一贯保存顾客的登陆名。 剩下的支出职业就与Forms身份认证没有太多的反差了。

回来顶端

在IIS中安顿Windows身份认证

与运用Forms身份ID明的次序分裂,使用Windows身份验证的次第必要万分的布局步骤。 那个小节将着重介绍在IIS中布署Windows身份ID明,我将常用的IIS6和IIS7.5为例分别介绍这一个配置。

IIS6的配置 请参照他事他说加以考查下图:

图片 16

 

IIS7.5的配置 请参照他事他说加以考察下图:

图片 17

小心:Windows居民身份表明是索要安装的,方法请参见下图:

图片 18

回去最上端

使用Active Directory验证客户地点

前方介绍了ASP.NET Windows身份ID明,在这里种办法下,IIS和WindowsAuthenticationModule为我们落到实处了客商身份认证的经过。 可是,不时恐怕由于各样原因,供给大家以编制程序的格局利用Active Directory验证客商身份,举个例子:在WinForm前后相继,也许别的的验证逻辑。

咱俩既能够从Active Directory中查询客户消息,也足以用它来兑现认证客户身份,那样便能够兑现团结的记名验证逻辑。

不管是如何运用Active Directory,大家都亟待运用DirectoryEntry和DirectorySearcher这么些指标。 DirectoryEntry还提供一个构造函数可让大家输入客户名和密码:

// 摘要:
//     初始化 System.DirectoryServices.DirectoryEntry 类的新实例。
//
// 参数:
//   Password:
//     在对客户端进行身份验证时使用的密码。DirectoryEntry.Password 属性初始化为该值。
//
//   username:
//     在对客户端进行身份验证时使用的用户名。DirectoryEntry.Username 属性初始化为该值。
//
//   Path:
//     此 DirectoryEntry 的路径。DirectoryEntry.Path 属性初始化为该值。
public DirectoryEntry(string path, string username, string password);

要落到实处自身的登入检查,就需求选择这么些构造函数。
以下是笔者写用WinForm写的贰个签到检查的示范:

private void btnLogin_Click(object sender, EventArgs e)
{
    if( txtUsername.Text.Length == 0 || txtPassword.Text.Length == 0 ) {
        MessageBox.Show("用户名或者密码不能为空。", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    string ldapPath = "LDAP://"   GetDomainName();
    string domainAndUsername = Environment.UserDomainName   "\"   txtUsername.Text;
    DirectoryEntry entry = new DirectoryEntry(ldapPath, domainAndUsername, txtPassword.Text);

    DirectorySearcher search = new DirectorySearcher(entry);

    try {
        SearchResult result = search.FindOne();

        MessageBox.Show("登录成功。", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch( Exception ex ) {
        // 如果用户名或者密码不正确,也会抛出异常。
        MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Stop);
    }
}

程序运转的作用如下:

图片 19

归来最上部

关于浏览器的报到对话框难点

当大家用浏览器访谈三个施用Windows身份验证的网址时,浏览器都会弹出三个对话框(左IE,右Safari):

图片 20

此刻,要求大家输入Windows的报到帐号,然后提交IIS验证身份。

第二回弹出这一个对话框很正规:因为程序要表达顾客的身份。 然则,每一遍关闭浏览器后一次再次展开页面时,又会师世此对话框,那时觉获得就特不方便人民群众了。 纵然有一点浏览器能记住客商名和密码,但笔者发觉FireFox,Opera,Chrome依旧会弹出那么些对话框,等待大家点击分明, 独有Safari才不会打扰顾客直接展开网页。IE的要命“记住小编的密码”复选框完全部都是个摆放,它根本不会记住密码!

进而,笔者所试过的具备浏览器中,唯有Safari是最人性化的。 纵然在暗中认可意况下,就算IE不会铭记密码,每趟都亟需再行输入。 然则,IE却能够支持不提示顾客输入登录帐号而一贯张开网页,那时候IE将利用顾客的当前Windows登陆帐号传递给IIS验证身份。

要让IE张开一个Windows居民身份申明的网址不晋升登入对话框,必需满足以下规范:

  1. 必须要在 IIS 的 Web 站点属性中启用 Windows 集成身份验证。 2. 客商端和Web服务器都必须要在依赖Microsoft Windows的同样个域内。 3. Internet Explorer 必需把所央求的 U奥迪Q5L 视为 Intranet(本地)。 4. Internet Explorer 的 Intranet 区域的安全性设置必须设为“只在 Intranet 区域自动登入”。 5. 乞请Web页的客户必需具备访问该Web页以至该Web页中引用的有所指标的贴切的文件系统(NTFS)权限。
  2. 顾客必得用域帐号登入到Windows 。

在此多少个原则中,假诺网址是在叁个Windows域中运维,除了第3条大概不满足外,此外条件应该都轻巧满意(第4条是私下认可值)。 因而,要让IE不提醒输入登陆帐号,只要确定保证第3条满意就足以了。 下边包车型客车图纸演示了怎么实现这么些布局:(注意:配置方式也顺应用域名访谈的图景)

图片 21

 

除此以外,除了在IE中设置Intranet外,还足以在访谈网址时,用微型Computer名取代IP地址大概域名, 那么IE始终以为是在寻访Intranet内的网址,那时也不会弹出登入对话框。

在这里,小编想再啰嗦三句: 1. IE在集成Windows居民身份申明时,即使不升迁登入对话框,可是不代表不安全,它会活动传送登入凭据。 2. 这种表现独有IE手艺帮忙。(此外的浏览器只是会记住密码,在完毕上实在是不相符的。)

  1. 集成Windows身份认证,也只符合在Intranet的遭受中央银行使。

再次回到顶端

安全上下文与客商模拟

在ASP.NET Windows身份认证情形中,与客商相关的安全上下文对象保存在HttpContext.User属性中,是一个档期的顺序为WindowsPrincipal的目的, 大家还足以访谈HttpContext.User.Identity来赢得经过身份认证的顾客标志,它是多个WindowsIdentity类型的对象。

在.NET Framework中,大家能够通过WindowsIdentity.GetCurrent()获取与日前线程相关的WindowsIdentity对象, 这种方式获得的是现阶段运转的Win32线程的安全上下文标志。 由于ASP.NET运维在IIS进度中,因而ASP.NET线程的巴中标志其实是从IIS的经过中承继的, 所以那个时候用三种办法得到的WindowsIdentity对象实际是莫衷一是的。

在Windows操作系统中,多数权力检查都以基于Win32线程的双鸭山上下文标志, 于是后边所说的三种WindowsIdentity对象会变成编制程序模型的不均等问题, 为了缓慢解决那一个难点,ASP.NET提供了“模拟”作用,允许线程以一定的Windows帐户的平安上下文来访谈能源。

为了能更加好的明白模拟的功能,小编企图了七个示范(ShowWindowsIdentity.ashx):

public class ShowWindowsIdentity : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        // 要观察【模拟】的影响,
        // 可以启用,禁止web.config中的设置:<identity impersonate="true"/>

        context.Response.ContentType = "text/plain";

        context.Response.Write(Environment.UserDomainName   "\"   Environment.UserName   "rn");

        WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;
        context.Response.Write(string.Format("HttpContext.Current.User.Identity: {0}, {1}rn", 
                winPrincipal.Identity.AuthenticationType, winPrincipal.Identity.Name));

        WindowsPrincipal winPrincipal2 = (WindowsPrincipal)Thread.CurrentPrincipal;
        context.Response.Write(string.Format("Thread.CurrentPrincipal.Identity: {0}, {1}rn",
                winPrincipal2.Identity.AuthenticationType, winPrincipal2.Identity.Name));

        WindowsIdentity winId = WindowsIdentity.GetCurrent();
        context.Response.Write(string.Format("WindowsIdentity.GetCurrent(): {0}, {1}",
                winId.AuthenticationType, winId.Name));
    }

首先,在web.config中设置:

<authentication mode="Windows" />

瞩目:要把网站安顿在IIS中,不然看不出效果。

当时,访谈ShowWindowsIdentity.ashx,将见到如下图所示的结果:

图片 22

到现在涂改一下web.config中装置:(潜心:后边加了一句配置

<authentication mode="Windows" />
<identity impersonate="true"/>

此刻,访谈ShowWindowsIdentity.ashx,将看见如下图所示的结果:

图片 23

说明:

  1. FISH-SENVISIONV二零零四是本人的测算机名。它在七个未有域的条件中。
  2. fish-li是自家的三个Windows帐号的登陆名。
  3. 网址陈设在IIS6中,进度以NETWORK SE奥迪Q5VICE帐号运营。
  4. 展开网页时,笔者输入的客户名是fish-li

日前二张图纸的差异之处其实也正是ASP.NET的“模拟”所表明的职能。

有关模拟,作者想说四点:
1. 在ASP.NET中,大家应有访问HttpContext.User.Identity获取当前客户标志,那么就不设卓殊(当时可以无需效法),举个例子FileAuthorizationModule正是这么管理的。
2. 模仿只是在ASP.NET应用程序访谈Windows系统能源时索要运用Windows的安检职能才会有用。

  1. Forms身份验证也能配置模拟作用,但必须要模拟三个Windows帐户。
  2. 大许多气象下是无需效法的。

再次来到最上端

在顾客端代码中访谈Windows身份申明的页面

在上篇博客中,小编身体力行了怎么用代码访谈叁个使用Forms身份验证的网址中的受限页面,方法是利用CookieContainer对象吸收服务端生的登入Cookie。 可是,在Windows居民身份评释的网址中,身份验证的进程发生在IIS中,并且根本不应用Cookie保存登陆情状,而是须求在伸手时发送必要的身份验证消息。

在利用代码做为客商端访谈Web服务器时,大家依旧须求运用HttpWebRequest对象。 为了能让HttpWebRequest在探问IIS时发送须要的身份验证消息,HttpWebRequest提供三个属性都能够产生这么些职能:

// 获取或设置请求的身份验证信息。
//
// 返回结果:
//     包含与该请求关联的身份验证凭据的 System.Net.ICredentials。默认为 null。
public override ICredentials Credentials { get; set; }


// 获取或设置一个 System.Boolean 值,该值控制默认凭据是否随请求一起发送。
//
// 返回结果:
//     如果使用默认凭据,则为 true;否则为 false。默认值为 false。
public override bool UseDefaultCredentials { get; set; }

下边是自家筹划的后生可畏体化的现身说法代码(注意代码中的注释)

static void Main(string[] args)
{
    try {
        // 请把WindowsAuthWebSite1这个网站部署在IIS中,
        // 开启Windows认证方式,并禁止匿名用户访问。
        // 然后修改下面的访问地址。
        HttpWebRequest request = 
            (HttpWebRequest)WebRequest.Create("http://localhost:33445/Default.aspx");

        // 下面三行代码,启用任意一行都是可以的。
        request.UseDefaultCredentials = true;
        //request.Credentials = CredentialCache.DefaultCredentials;
        //request.Credentials = CredentialCache.DefaultNetworkCredentials;
        // 如果上面的三行代码全被注释了,那么将会看到401的异常信息。

        using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() ) {
            using( StreamReader sr = new StreamReader(response.GetResponseStream()) ) {
                Console.WriteLine(sr.ReadToEnd());
            }
        }
    }
    catch( WebException wex ) {
        Console.WriteLine("=====================================");
        Console.WriteLine("异常发生了。");
        Console.WriteLine("=====================================");
        Console.WriteLine(wex.Message);
    }
}

实则根本部分照旧安装UseDefaultCredentials只怕Credentials,代码中的三种情势是卓有成效的。 这两种格局的出入: 1. Credentials = CredentialCache.DefaultCredentials; 表示在出殡和安葬央浼会带被欺诈前客商的身份验证凭据。 2. UseDefaultCredentials = true; 此方法在里边会调用前边的不二等秘书籍,由此与日前的格局是均等的。 3. Credentials = CredentialCache.DefaultNetworkCredentials; 是在.NET 2.0中援用的新点子。

至于DefaultCredentials和DefaultNetworkCredentials的越来越多差异,请看自个儿收拾的表格:

Credentials属性

证明类型

实例类型

.NET补助版本

DefaultCredentials

ICredentials

SystemNetworkCredential

从1.0开始

DefaultNetworkCredentials

NetworkCredential

SystemNetworkCredential

从2.0开始

多少个品种的一而再接二连三关系: 1. NetworkCredential达成了ICredentials接口, 2. SystemNetworkCredential承接自NetworkCredential。

 

在终结那篇博客以前,笔者想本身应该谢谢新蛋。 在新蛋的互连网情状中,让自家学会了使用Windows身份验证。 除了感激之外,小编前几日还专程记挂 fl45 这么些登陆名......

在IIS中配备Windows居民身份注解

与利用Forms身份验证的次第差异,使用Windows身份认证的程序必要额外的配置步骤。 这一个小节将重点介绍在IIS中布局Windows身份验证,我将常用的IIS6和IIS7.5为例分别介绍那个安顿。

IIS6的配置 请参照他事他说加以调查下图:

图片 24

 

IIS7.5的配置 请参照他事他说加以考察下图:

图片 25

介怀:Windows身份验证是内需设置的,方法请参谋下图:

图片 26

归来顶上部分

至于浏览器的登入对话框问题

当大家用浏览器访谈贰个采纳Windows居民身份注脚的网址时,浏览器都会弹出叁个会话框(左IE,右Safari):

图片 27

当时,要求大家输入Windows的登入帐号,然后提交IIS验证身份。

第三次弹出那几个对话框很正规:因为程序要注明顾客的地位。
而是,每一次关闭浏览器后一次再度打开页面时,又会现出此对话框,那时候以为就非常不低价了。
固然有一点浏览器能记住客商名和密码,但本身意识FireFox,Opera,Chrome还是会弹出那些对话框,等待大家点击显明, 独有Safari才不会骚扰客商直接打开网页。 IE的要命“记住作者的密码”复选框完全部是个摆放,它根本不会记住密码!

故此,小编所试过的有所浏览器中,唯有Safari是最人性化的。
即便在默许景况下,即使IE不会铭记密码,每便都亟需重新输入。
不过,IE却得以协助不提示客商输入登入帐号而直白伸开网页, 当时IE将使用顾客的当前Windows登入帐号传递给IIS验证身份。

要让IE展开多少个Windows身份ID明的网站不提示登入对话框,必需满足以下准绳:

  1. 必需在 IIS 的 Web 站点属性中启用 Windows 集成身份验证。
  2. 顾客端和Web服务器都一定要在依据Microsoft Windows的平等个域内。
  3. Internet Explorer 必须把所要求的 U科雷傲L 视为 Intranet(本地)。
  4. Internet Explorer 的 Intranet 区域的安全性设置必得设为“只在 Intranet 区域活动登陆”。
    5. 呼吁Web页的顾客必需具备访谈该Web页以至该Web页中引用的有所目的的善刀而藏的文件系统(NTFS)权限。
  5. 客商必需用域帐号登陆到Windows 。

在这里多少个标准化中,假诺网址是在多少个Windows域中运作,除了第3条也许不满意外,此外条件应该都轻易满意(第4条是默许值)。 因而,要让IE不提醒输入登陆帐号,只要确认保障第3条满意就足以了。 上面的图样演示了何等产生这一个布局:(注意:配置格局也切合用域名访谈的境况)

图片 28

 

除此以外,除了在IE中设置Intranet外,还是可以在做客网址时,用微型Computer名替代IP地址或许域名, 那么IE始终感觉是在访问Intranet内的网址,那时候也不会弹出登陆对话框。

在那,笔者想再啰嗦三句:
1. IE在集成Windows身份ID明时,就算不提拔登入对话框,但是不意味不安全,它会自行传递登陆凭据。
2. 这种表现独有IE工夫帮助。(其余的浏览器只是会铭记密码,在促成上其实是不相似的。)

  1. 集成Windows居民身份申明,也只切合在Intranet的条件中接受。

归来顶上部分

在客商端代码中做客Windows居民身份申明的页面

在上篇博客中,小编以身作则了如何用代码访谈三个使用Forms居民身份注明的网址中的受限页面,方法是采纳CookieContainer对象吸取服务端生的记名Cookie。 但是,在Windows身份认证的网址中,身份验证的历程爆发在IIS中,并且根本不行使Cookie保存登入情状,而是必要在号令时发送必要的身份验证音信。

在使用代码做为客商端访谈Web服务器时,大家照样须求选择HttpWebRequest对象。 为了能让HttpWebRequest在寻访IIS时发送须求的身份验证音信,HttpWebRequest提供一个特性都足以实现那么些效应:

// 获取或设置请求的身份验证信息。
//
// 返回结果:
//     包含与该请求关联的身份验证凭据的 System.Net.ICredentials。默认为 null。
public override ICredentials Credentials { get; set; }


// 获取或设置一个 System.Boolean 值,该值控制默认凭据是否随请求一起发送。
//
// 返回结果:
//     如果使用默认凭据,则为 true;否则为 false。默认值为 false。
public override bool UseDefaultCredentials { get; set; }

上面是作者希图的完好的示范代码(注意代码中的注释)

static void Main(string[] args)
{
    try {
        // 请把WindowsAuthWebSite1这个网站部署在IIS中,
        // 开启Windows认证方式,并禁止匿名用户访问。
        // 然后修改下面的访问地址。
        HttpWebRequest request = 
            (HttpWebRequest)WebRequest.Create("http://localhost:33445/Default.aspx");

        // 下面三行代码,启用任意一行都是可以的。
        request.UseDefaultCredentials = true;
        //request.Credentials = CredentialCache.DefaultCredentials;
        //request.Credentials = CredentialCache.DefaultNetworkCredentials;
        // 如果上面的三行代码全被注释了,那么将会看到401的异常信息。

        using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() ) {
            using( StreamReader sr = new StreamReader(response.GetResponseStream()) ) {
                Console.WriteLine(sr.ReadToEnd());
            }
        }
    }
    catch( WebException wex ) {
        Console.WriteLine("=====================================");
        Console.WriteLine("异常发生了。");
        Console.WriteLine("=====================================");
        Console.WriteLine(wex.Message);
    }
}

实际上根本部分仍旧设置UseDefaultCredentials可能Credentials,代码中的三种艺术是卓有成效的。
这三种办法的差异:

  1. Credentials = CredentialCache.DefaultCredentials; 表示在出殡和安葬央浼会带上圈套前客商的身份验证凭据。
  2. UseDefaultCredentials = true; 此方法在里边会调用后面的格局,因而与日前的方法是生龙活虎致的。
  3. Credentials = CredentialCache.DefaultNetworkCredentials; 是在.NET 2.0中援用的新方式。

关于DefaultCredentials和DefaultNetworkCredentials的越来越多差距,请看自己整理的报表:

Credentials属性

发明类型

实例类型

.NET扶助版本

DefaultCredentials

ICredentials

SystemNetworkCredential

从1.0开始

DefaultNetworkCredentials

NetworkCredential

SystemNetworkCredential

从2.0开始

四个系列的持续关系:

  1. NetworkCredential实现了ICredentials接口,
  2. SystemNetworkCredential继承自NetworkCredential。

 

在完工那篇博客以前,笔者想本人应该多谢新蛋。
在新蛋的网络境况中,让小编学会了使用Windows身份验证。
除开谢谢之外,笔者前日还特意回顾 fl45 那么些登陆名......

转自:

本文由pc28.am发布于计算机编程,转载请注明出处:判断用户是否对路径拥有访问权限,Windows身份认

上一篇:不等引用地址,jquery全体版本在线引用 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • 判断用户是否对路径拥有访问权限,Windows身份认
    判断用户是否对路径拥有访问权限,Windows身份认
    何以收获当前系统客商对文本/文件夹的操作权限? 细说ASP.NET Windows身份认证 开卷目录 开始 认知ASP.NETWindows身份申明 访问 ActiveDirectory 在ASP.NET中访问Acti
  • 一些很酷的,获取本地磁盘信息
    一些很酷的,获取本地磁盘信息
    直接上干货简单易懂 原作出处:http://www.codeproject.com/useritems/tips.asp?df=100 //磁盘监控(远程/本地) //需要引用System.Management.dll public class RemoteMonitoring { pri
  • 福寿康宁劳务端webSocket连接通信
    福寿康宁劳务端webSocket连接通信
    前言 近日socket通讯使用TCP、UDP协调,个中TCP公约相对来说相比较安全和谐!本文也是来说学TCP为主(恕在下学艺不精)。      上面是私人商品房精晓的
  • 编写翻译安装javascript,Centos系统一整合体安装
    编写翻译安装javascript,Centos系统一整合体安装
    3,解压安装,设置安装路线 tar zxvf Python-3.6.5.tgz mkdir /usr/local/python365 cd Python-3.6.5 ./configure --prefix=/usr/local/python365 make make install   解释: tar是解压tgz包 ./
  • 如何在手机上实现饼图图表
    如何在手机上实现饼图图表
    最前方的话:Smobiler是一个在VS意况中使用.Net语言来开采APP的开辟平台,也许比Xamarin更低价   生机勃勃、指标准样本式 咱俩要兑现上海教室中的效果,需