配置安全鉴别

鉴别是指鉴定来访用户是否合法的过程。ASP.NET Framework支持三种鉴别类型:

Windows鉴别;

NET Passport鉴别;

Forms鉴别。

对于某一特定的应用程序,同一时刻只能启用其中一种鉴别方式。例如,不能在同一时刻同时启用Windows鉴别和Forms鉴别。

在默认情况下,系统将启用Windows鉴别。当Windows鉴别启用后,用户通过微软Windows系统的账户名进行验证。此时的角色对应于微软Windows系统中的用户组。

Windows鉴别将验证用户的职责委派给了IIS(因特网信息服务器端)。通过对IIS进行配置,IIS可以使用基本、Windows集成和明文鉴别三种验证方式。

.NET Passport鉴别是诸如MSN和Hotmail这样的微软Web站点使用的鉴别类型。如果希望用户使用其Hotmail账号和密码来登录到应用程序中,那么可以启用.NET Passport鉴别来进行用户验证。

注解   在使用微软.NET Passport鉴别之前,必须要下载并安装微软.NET Passport SDK,并在微软网站进行注册并向微软付费。要了解更多相关信息,可以参看MSDN网站(http://msdn.microsoft.com)。

最后一种鉴别是Forms鉴别。启用Forms鉴别后,通常会使用cookie来验证用户(详细内容见下一节)。一旦用户通过鉴别,一个加密的cookie信息就会添加到用户的浏览器中。当该用户从一个页面进入另一个页面时,系统的鉴别程序将通过cookie类来进行用户合法性验证。

启用Forms鉴别后,用户和角色信息就会被保存到自定义的数据区域中。也就是说可以将用户信息保存到你所希望的任何地方。例如,可以将用户名和密码保存到数据库、XML文件或者甚至是纯文本文件中。

在前一版本的ASP.NET中,如果使用Forms鉴别,就要编写所有保存和获取用户信息的代码。而创建ASP.NET 2.0应用程序,则可以让ASP.NET Membership来为你完成所有这些工作。使用ASP.NET Membership可以处理保存、获取用户以及角色信息的所有细节。

通过配置应用程序根目录下的Web配置文件,可以为我们的应用程序启用特定的鉴别类型。代码清单2-1中的文件配置并启用了Forms鉴别。

代码清单2-1 Web.Config

<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms" />
</system.web>
</configuration>

代码清单2-1中,authentication节点的mode属性设置为Forms。该mode属性可能的取值有None、Windows、Forms和Passport。

注解   Windows、Forms和Passport鉴别实现在HTTP模块之中。如果要实现自定义的鉴别结构,就要创建自定义的HTTP模块。Visual Web 如果你愿意,可以通过站点配置工具来为应用程序启用特殊的鉴别类型。该工具以表单界面提供了对Web配置文件的修改功能。通过选取菜单选项WebSite(站点)→ASP.NET Configuration(ASP.NET配置),便可以打开站点管理工具。

配置Forms鉴别

Forms鉴别的几个配置细节:

cookieless——用于配置应用程序即使浏览器不支持cookie特性,也能使用Forms鉴别。可能的取值有UseCookies、UseUri、AutoDetect和UseDeviceProfile。默认值是UseDeviceProfile;

defaultUrl——用于指定用户通过鉴别后重定向的目标。默认值是Default.aspx;

domain——用于指定与鉴别cookie相关的域。默认值是空字符串;

enableCrossAppRedirects——用于通过传递查询字符串中的鉴别凭证来在应用程序之间鉴别用户。默认值是false;

loginUrl——用于指定Login页面的路径。默认值是Login.aspx;

name——用于指定鉴别cookie的名字。默认值为.ASPXAUTH;

path——用于指定和鉴别与cookie相关联的路径。默认值是/;

protection——用于指定如何对鉴别cookie进行加密。可能的取值有All、Encryption、None和Validation。默认值是All;

requiresSSL——用于指定在传递鉴别cookie时是否需要使用SSL(安全套接字层)连接。默认值是false;

slidingExpiration——用于防止鉴别cookie在连续周期性访问中过期。可能的取值是true或false;

timeout——用于指定以分钟为单位的鉴别cookie的过期时间数。默认值是30。

这些配置设置中的几个特性与鉴别cookie有关。例如,可以使用代码清单2-2中的Web配置文件来改变鉴别cookie的名称。

代码清单2-2 Web.Config

<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms name="MyApp" />
</authentication>
</system.web>
</configuration>

这些选项中的其他部分还需另加说明。在下面的章节中,将介绍如何使用无cookie鉴别,修改cookie过期策略并启用应用程序间鉴别。

使用无cookie的Forms鉴别

通常情况下,Forms鉴别使用cookie来对用户进行识别。然而,Forms鉴别还支持一个名为无cookie鉴别的特性。启用无cookie鉴别后,就可以在不依靠浏览器cookie的情况下识别用户。

利用无cookie鉴别功能,将可以在不支持cookie或禁用了cookie功能的浏览器中使用Forms鉴别和ASP.NET Membership。

当启用无cookie鉴别功能后,用户将通过一串添加到页面URL中的唯一的字符串标识来进行识别。如果用户在应用程序的相关页面间来回导航,那么字符串标识也将自动地在这些页面间进行传递,同时应用程序会在这样的页面交叉请求中自动识别用户。

当访问一个需要鉴别且又开启了无cookie鉴别功能的页面时,浏览器地址栏中的URL看起来将会像这样:

http://localhost:2500/Original/(F(WfAnevWxFyuN4SpenRclAEh_lY6OKWVllOKdQkRk

tOqV7cfcrgUJ2NKxNhH9dTA7fgzZ-cZwyr4ojyU6EnarC-bbf8g4sl6m4k5kk6Nmcsg1))/

SecretFiles/Secret2.aspx

在URL中那串又长又丑的代码就是编码过的用户鉴别凭证。

Web配置文件中的forms节点的cookieless属性被用来配置无cookie鉴别的类型。cookieless属性可以接受下列四种类型中的任意一种:

UseCookies——总是使用cookie进行鉴别,无论浏览器或设备是否支持cookie;

UseUri——使用查询字符串保存鉴别标识,无论浏览器或设备是否支持cookie;

AutoDetect——ASP.NET自动检测浏览器或设备是否支持cookie,从而确定如何传递用户识别凭证;

UseDeviceProfile——ASP.NET根据System.Web.HttpBrowserCapabilities设置来确定是否使用cookie来传递用户识别凭证。

该属性的默认值是UseDeviceProfile。在默认情况下,只有当特定的设备类型支持cookie时,ASP.NET Framework才会生成cookie信息。ASP.NET Framework通过下面的目录中的一组文件来维护一个设备性能数据库。

\WINDOWS\Microsoft.NET\Framework\[version]\CONFIG\Browsers

默认情况下,在使用诸如微软IE这样的浏览器时,ASP.NET Framework根本不使用无cookie鉴别。根据IE的设备特性,IE支持cookie,所以一般情况下不会使用无cookie鉴别。即使浏览器的cookie功能被禁用,该框架也不会使用无cookie鉴别。

如果希望ASP.NET Framework能自动检测浏览器是否支持cookie功能,那么必须将cookieless属性值设置为AutoDetect。当开启了AutoDetect后,ASP.NET Framework将检查浏览器是否发送了HTTP COOKIE协议标识。如果发现有COOKIE协议标识,那么鉴别cookie将传给浏览器。否则,ASP.NET Framework使用无cookie鉴别。

代码清单2-3中的Web配置文件启用了AutoDetect功能。

代码清单2-3 Web.Config

<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms cookieless="AutoDetect"/>
</authentication>
</system.web>
</configuration>

在Forms鉴别中使用超时限制

在默认情况下,Forms鉴别使用超时限制策略。即用户在30分钟以内没有请求任何页面,那么该用户仍然处于已鉴别状态。如果用户在合法登录后超过连续30分钟未访问任何页面,那么该用户将自动登出应用程序。

如果需要十分严格的安全限制条件,那么可以使用比超时限制更安全一些的绝对限制策略。换言之,应用程序可以强制用户在一个指定的周期时间内再次登录。

代码清单2-4中的Web配置文件强制用户每分钟都进行一次登录。

代码清单2-4 Web.Config

<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms slidingExpiration="false" timeout="1" />
</authentication>
</system.web>
</configuration>

跨应用程序使用Forms鉴别

在默认情况下,Forms鉴别是和应用程序密切相关的。换句话说,如果用户登录到了某一应用程序中,但是该用户却并未在任何其他应用程序中被鉴别——即使另外的应用程序和该用户已登录的应用程序位于同一台Web服务器端上。

由此所引起的问题表现在两个方面。
第一,你不希望公司的员工在不同的公司应用程序间切换时进行多次登录。每个员工应该可以只登录一次,就能自动地使用公司所提供的所有应用程序。

第二,如果你在运行一个Web服务器端集群(Web Farm),那么你一定不希望用户在访问Web服务器端所提供的不同服务时都进行登录。从用户的角度,Web服务器端集群可以看成是一个单一的服务器端。

在默认情况下,Forms鉴别的cookie是会加密和签名的。此外,每个应用程序默认都会各自生成独立的解密和校验码。因此,默认情况下也不能在应用程序间共享鉴别cookie。

通过Web配置文件的machineKey节点,可以设置该加密密钥和校验码:

<machineKey decryption="Auto" validation="SHA1" decryptionKey="AutoGenerate, IsolateApps" validationKey="AutoGenerate, IsolateApps" />

解码(decryption)属性用于指定Forms鉴别中cookie的加密和解密算法,其取值有Auto、AES(政府标准加密算法)或3DES(三倍加密强度的DES)。decryption属性默认值为Auto,该值说明ASP.NET Framework将基于当前Web服务器端的性能来选取综合性能最佳的加密算法。

验证(validation)属性指定用于对鉴别cookie进行散列和加密的算法,其取值为AES、MD5、SHA1或TripleDES(即3DES)。

decryptionKey属性表示用于对鉴别cookie进行加密和解密的密钥。validationKey表示用于对鉴别cookie进行签名的验证码。在默认情况下,这两个属性值都会被设置为AutoGenerate,该值表示ASP.NET Framework将产生随机密钥,并将其存储在LSA(本地安全鉴别)中。

需要注意的是,decryptionKey和validationKey两个属性都包含一个IsolateApps修饰符。当IsolateApps修饰符出现时,将为同一Web服务器端上的每个应用程序创建唯一的密钥。

如果希望在同一Web服务器端上的不用应用程序之间共享同一鉴别cookie信息,那么则需要重写服务器端上Web配置文件中的machineKey节点,并从该节点的decryptionKey和validationKey两个属性中去掉IsolateApps修饰符。即可以在Web配置文件的System.Web节点中的任意位置添加如下machineKey节点:

<machineKey decryption="Auto" validation="SHA1" decryptionKey="AutoGenerate" validationKey="AutoGenerate" />

根Web配置文件位于下面的路径:

C:\WINDOWS\Microsoft.NET\Framework\[version]\CONFIG\Web.Config

另一方面,如果要共享不同Web服务器端上的应用程序的鉴别cookie信息,那么就需要手动指定decryptionKey和validationKey的属性值。由于需要共享不同Web服务器端上的密钥,所以就不能让ASP.NET Framework来自动产生这些密钥。

例如,下面的machineKey节点中包含了显式指定的加密和验证密钥:

<machineKey
decryption="AES"
validation="SHA1"
decryptionKey="306C1FA852AB3B0115150DD8BA30821CDFD125538A0C606DACA53DBB3C3E0AD2"
validationKey="61A8E04A146AFFAB81B6AD19654F99EA7370807F18F5002725DAB98B8EFD19C711337E26948E26D1D 174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265" />

当使用AES算法时,需要一个64位的十六进制字符随机序列。当使用SHA1算法时,需要一个128位的十六进制字符随机序列。代码清单2-5中的页面可以用来生成这样的随机字符串序列(见图2-1)。

代码清单2-5 GenerateKeys.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> void Page_Load()
{
lblAES.Text = GetSequence(64);
lblSHA1.Text = GetSequence(128);
} private string GetSequence(int length)
{
byte[] buffer = new byte[length / 2];
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
provider.GetBytes(buffer);
StringBuilder builder = new StringBuilder(length); for (int i = 0; i < buffer.Length; i++)
{ builder.Append(string.Format("{0:X2}", buffer[i])); } return builder.ToString();
} </script> <html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Generate Keys</title>
</head>
<body>
<form id="form1" runat="server">
<div>
AES:
<asp:Label ID="lblAES" runat="server" />
<br /> SHA1:
<asp:Label ID="lblSHA1" runat="server" />
</div>
</form>
</body> </html>
<%-- --%>

图2-1 创建加密密钥

代码清单2-5中的页面使用RNGCryptoServiceProvider来生成随机序列。调用GetBytes()方法将返回该随机加密密钥。

注解   这里的GenerateKey.aspx页面基于文章《如何:在ASP.NET 2.0中配置MachineKey》(How To:Configure MachineKey in ASP.NET 2.0)中的代码示例,该文位于微软MSDN站点中(http://msdn.microsoft.com)。

显式指定了密钥的machineKey节点既可以加入服务器端的Web配置文件,也可以加入特定应用程序的Web配置文件。如果不希望同一Web服务器端上的所有应用程序之间都共享同一密钥,那么就只应将该machineKey节点加入到需要相互共享的应用程序的配置文件中。

跨域使用Forms鉴别

在上一节中,介绍了如何在同一个Web服务器端或不同Web服务器端中的多个应用程序之间共享同一个鉴别cookie。但是如何才能在多个域之间共享同一个鉴别cookie呢?

浏览器的cookie总是和Web站点的域相关的。例如,Amazon站点不能读取Barnes和Noble站点所设置的cookie信息,这是一个很好的设计。可是,你可能会发现你需要在不同域的站点之间共享鉴别信息。

解决这个问题的方法是使用查询字符串来代替cookie传递鉴别凭证。因为在不同的域之间传递查询字符串是没有任何障碍的。

要应用到这样的场景中,必须要配置应用程序能接受通过查询字符串传递的鉴别凭证。代码清单2-6中的Web配置文件包含了一个enableCrossAppRedirects属性,通过设置该属性可以启用跨域的鉴别凭证共享。

代码清单2-6 Web.Config

<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms enableCrossAppRedirects="true" />
</authentication>
<machineKey decryption="AES" validation="SHA1" decryptionKey="306C1FA852AB3B0115150DD8BA30821CDFD125538A0C606DACA53DBB3C3E0AD2" validationKey="61A8E04A146AFFAB81B6AD19654F99EA7370807F18F5002725DAB98B8EFD19C711337E26948E26D1D174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265" />
</system.web> </configuration>

如果将代码清单2-6中的Web配置文件添加到位于不同域中的两个应用程序中后,这两个应用程序就将能共享同一个鉴别凭证。

注意   为了确保代码清单2-6中所指定的验证和加密密钥格式正确,可以通过使用上一节中我们所讨论的GenerateKeys.aspx页面来生成新的随机密钥。

当连接或从一个应用程序重定向到另一个应用程序时,必须通过查询字符串参数来传递鉴别凭证。代码清单2-7中的页面将必要的查询字符串参数添加到了超链接中。

代码清单2-7 QueryStringAuthenticate.aspx

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
void Page_Load()
{
string cookieName = FormsAuthentication.FormsCookieName;
string cookieValue = FormsAuthentication.GetAuthCookie(User.Identity.Name, false).Value;
lnkOtherDomain.NavigateUrl += String.Format("?{0}={1}", cookieName, cookieValue);
}
</script> <html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Query String Authenticate</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:HyperLink ID="lnkOtherDomain" Text="Link to Other Domain" NavigateUrl="http://www.OtherDomain.com/Secret.aspx" runat="server" />
</div>
</form>
</body>
</html>

使用FormsAuthentication类

使用Froms鉴别的主要API是FormsAuthentication类。该类支持下列属性:

CookieDomain——用于返回鉴别cookie关联的域;

CookieMode——用于返回cookieless鉴别模式。可能的取值有AutoDetect、UseCookies、Use- DeviceProfile和UseUri;

CookiesSupported——如果浏览器支持cookie和Forms鉴别,并同时启用了cookie功能,那么将返回true;

DefaultUrl——用于返回用户鉴别成功后所转向的页面URL;

EnableCrossAppRedirects——当鉴别凭证可以通过查询字符串进行传递时,该属性返回true;

FormsCookieName——用于返回鉴别cookie的名字;

FormsCookiePath——用于返回和鉴别cookie相关联的路径;

LoginUrl——用于返回用户鉴别时所转向的页面URL;

RequireSSL——如果鉴别cookie必须使用SSL协议来传输,则该属性返回true;

SlidingExpiration——如果鉴别cookie使用超时限制策略,那么该属性返回true。

这些属性主要用于返回Web配置文件中对Forms鉴别的配置信息。

FormsAuthentication类还支持以下的方法:

Authenticate——用于根据存储在Web配置文件中的用户名和密码来验证用户名和密码;

Decrypt——用于解密鉴别cookie;

GetAuthCookie——用于获取鉴别cookie;

GetRedirectUrl——用于获取重定向到Login页面上前的原始页面路径;

HashPasswordForStoringInConfigFile——用于对将要存入Web配置文件中的密码进行散列;

RedirectFromLoginPage——用于使用户返回重定向到Login页面前的原始页面;

RedirectToLoginPage ——用于将用户请求重定向到Login页面;

RenewTicketIfOld——用于更新已过期的鉴别cookie凭证;

SetAuthCookie——用于创建和发布鉴别cookie;

SignOut——用于移除用户鉴别cookie并同时使其登出应用程序。

使用FormsAuthentication类的属性和方法可以构建一个用户注册和登录系统,而无须使用ASP.NET Membership。例如,代码清单2-8中的Web配置文件包含了一个用户名和密码的列表。

代码清单2-8 Web.Config

<?xml version="1.0" ?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms>
<credentials passwordFormat="Clear">
<user name="Bill" password="secret" />
<user name="Jane" password="secret" />
<user name="Fred" password="secret" />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>

代码清单2-8中的Web配置文件包含了一个forms节点,该forms节点内包含了一个credentials节点。而credentials节点内又包含了一个用户名和密码列表。

需要注意的是credentials节点包含了一个passwordFormat属性,该属性值为Clear。如果需要,可以存放散列过的密码来代替明文密码。这样一来,对于任何可以操作该服务器端的人来说,都不能看到用户的实际密码了。属性passwordFormat的另外两个可能的取值是MD5和SHA1。

注解   如果需要对密码进行散列并存储在Web配置文件中,那么可以使用(某一变量名)FormsAuthentication.HashPasswordForStoringInConfigFile()方法。该方法需要使用一个明文密码和一个散列算法名作为其调用参数,然后执行返回该密码的散列版本。

代码清单2-9中的Login页面包含了一个用户名(User Name)和密码(Password)文字输入框(见图2-2)。

图2-2 依靠Web配置文件中的信任设置来鉴别用户

代码清单2-9 FormsLogin.aspx

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected void btnLogin_Click(object sender, EventArgs e)
{
if (FormsAuthentication.Authenticate(txtUserName.Text, txtPassword.Text))
{
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, chkRememberMe.Checked);
}
else
{ lblError.Text = "Invalid user name/password"; }
} </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server">
<title>Forms Login</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblError" EnableViewState="false" ForeColor="Red" runat="server" /> <br />
<br /> <asp:Label ID="lblUserName" Text="User Name:" AssociatedControlID="txtUserName" runat="server" /> <br />
<asp:TextBox ID="txtUserName" runat="server" />
<br />
<br /> <asp:Label ID="lblPassword" Text="Password:" AssociatedControlID="txtPassword" runat="server" />
<br />
<asp:TextBox ID="txtPassword" TextMode="Password" runat="server" /> <br />
<br />
<asp:CheckBox ID="chkRememberMe" Text="Remember Me" runat="server" /> <br />
<br />
<asp:Button ID="btnLogin" Text="Login" OnClick="btnLogin_Click" runat="server" />
</div>
</form>
</body>
</html>

当点击上图所示的Login按钮后,系统将会调用btnLogin_Click()事件处理函数,并使用FormsAuthentication.Authenticate()方法来检查通过文本输入框(TextBox)控件输入的用户名和密码是否与Web配置文件中的用户名和密码匹配。如果用户鉴别成功,那么将会调用FormsAuthentication.RedirectFromLoginPgae()方法。

调用RedirectFromLoginPage()方法主要将完成两件事。该方法会将鉴别cookie凭证加入到用户的浏览器中,然后将页面重定向回进入Login页面时的原始页面。如果用户直接请求了Login页面,那么鉴别成功后将重定向到该应用程序的Default.aspx页面。

传给RedirectFromLoginPage()方法的第二参数,用于表示是否只创建当前会话(Session)还是持久化鉴别cookie。如果创建持久化鉴别cookie,那么用户以后访问该Web站点时就不需要再次进行登录。

使用User类

通过Page.User和HttpContext.User属性可以获取当前用户的用户信息。Page.User属性公开了Principal对象,该对象支持下列方法:IsInRole——用于检查某一用户是否属于指定的角色中。

例如,如果启用了Windows集成鉴别,那么就可以使用IsInRole()方法来检查某一用户是否属于特定的微软Windows组,比如BUILTIN\Administrators中的成员:

if ( User.IsInRole("BUILTIN\Administrators") )
{ // 执行一些只有Administrator才能进行的操作 }

注解   如果角色管理器已启用,那么使用User.IsInRole()方法在Windows组中做检查之前,必须对角色管理器进行配置,以使其使用WindowsTokenRoleProvider提供器。

Principal对象还包含了Identity属性,该属性可以用来获取当前用户的用户标识信息。Identity对象支持下列三个属性:

AuthenticationType ——用于确定用户是如何进行鉴别的。可能的取值是Forms、Basic和NTLM;

IsAuthenticationd——用于确定用户是否已通过鉴别;

Name——用于获取用户名。

如果要获取当前用户的用户名,那么可以使用像这样的逻辑:

String name = User.Identity.Name;

如果用户未通过鉴别,User.Identity.Name属性将返回空字符串。

FormsAuthentication使用指南的更多相关文章

  1. FormsAuthentication 使用指南

    配置安全鉴别 鉴别是指鉴定来访用户是否合法的过程.ASP.NET Framework支持三种鉴别类型: Windows鉴别: NET Passport鉴别: Forms鉴别. 对于某一特定的应用程序, ...

  2. FormsAuthentication使用指南,实现登录

    一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到Session中存储的用户基本信息,查看比较他有没有登录和能否访 ...

  3. C#微信公众号开发系列教程二(新手接入指南)

    http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...

  4. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  5. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

  6. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  7. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

  8. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  9. Atitit.研发管理软件公司的软资产列表指南

    Atitit.研发管理软件公司的软资产列表指南 1. Isv模型下的软资产1 2. 实现层面implet1 3. 规范spec层1 4. 法则定律等val层的总结2 1. Isv模型下的软资产 Sof ...

随机推荐

  1. sort函数使用自定义数据排序使用

    package main import ( "fmt" "sort" ) type ServerSlice []Server type Server struc ...

  2. php函数基本语法之自定义函数

    PHP提供了功能强大的函数,但这远远满足不了需要,程序员可以根据需要自己创建函数.本节就开始学习创建函数的方法.大理石平台价格表 我们在实际开发过程当中需要有很多功能都需要反复使用到,而这些反复需要使 ...

  3. QEventLoop以及QT事件循环

    1.一般我们的事件循环都是由exec()来开启的,例如下面的例子: 1 QCoreApplicaton::exec() 2 QApplication::exec() 3 QDialog::exec() ...

  4. C 指针常量 和常量指针 指向常量的指针常量的使用

    #include <stdio.h> /* 指针常量 和常量指针 指向常量的指针常量 */ int main() { int a = 100; int b =200; int* const ...

  5. AtCoder Grand Contest 008题解

    传送门 \(A\) 分类讨论就行了 然而我竟然有一种讨论不动的感觉 int x,y; inline int min(R int x,R int y){return x<y?x:y;} inlin ...

  6. package.json 版本号解释

    经常看到package.json中的各种版本号记录 比如 ~ ^ 等.其实是有个规范的.其遵循 semver. 具体的网站为:  http://semver.org/lang/zh-CN/

  7. [golang]A modern, fast and scalable websocket framework with elegant API written in Go

    A modern, fast and scalable websocket framework with elegant API written in Go http://bit.ly/neffos- ...

  8. 9.本地线程(ThreadLoca)

    ThreadLoca 提高一个线程的局部变量,访问某个线程都有自己的局部变量,当使用ThreadLoca为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本,二不会影响到 ...

  9. python3 枚举定义和使用

    定义 在某些情况下,一个类的对象是有限且固定的,比如季节类,它只有 4 个对象:再比如行星类,目前只有 8 个对象.这种实例有限且固定的类,在 Python 中被称为枚举类.程序有两种方式来定义枚举类 ...

  10. 沸腾换热UDF【转载】

    #include "udf.h"    //包括常规宏 #include "sg_mphase.h"    // 包括体积分数宏 CVOF(C,T) #defi ...