1. 身份验证和授权
1.1. 身份验证
在.NET中提供了身份验证和授权来保证程序的安全,提供forms身份验证和登录系列控件相结合的方式可以提供更加完善的用户管理功能,可以较好的提供授权管理范围。身份验证指的是根据用户的验证消息来识别他的身份。
在.NET中身份验证主要有三种方式,分别是Forms、Windows和Passport。
其中Forms指的是在开发者所在的服务器上来实现,其验证流程如图所示:
Forms主要有三种方式来验证用户资料:
在代码中直接验证。即要验证的信息写死在代码中,无法再更改。
利用数据库实现验证。即把信息存储到数据库中,要验证时通过查询数据库进行匹配验证。
利用配置文件直接验证。使用FormsAuthentication类对ASP.NET的配置文件进行配置
对于FormsAuthentication类而言,它有以下一些常用属性和方法:
1.2. 授权
授权指的是确定提供验证的用户可以访问哪些资源。ASP.NET中提供了两种授权方式,分别是:
文件授权,指的是验证远程用户是否有权限访问所请求的文件,主要通过检查.aspx或者.asmx的访问控制列表来确定是否具有权限,通常使用FileAuthorizationModule类来实现;
URL授权,指的是验证远程用户是否有权限访问所请求的url,主要通过将用户和角色映射到ASP.NET应用程序的url中,通常使用UrlIAuthorizationModule类来实现
要使用URL授权需要在web.configure中配置<authorization>节,在其中指定用于授予访问权限的<allow>和用于撤销访问权限的<deny>标签,例如:
<authorization> <!--users 用于标识目标身份; roles用于标识请求角色;verbs用来定义http方法--> <allow users= "逗号分割的用户列表" roles= "逗号分割的角色列表" verbs= "逗号分割的HTTP请求列表" /> <deny users= "逗号分割的用户列表" roles="逗号分割的角色列表" verbs= "逗号分割的HTTP请求列表" /> </authorization>
2. 登录控件
2.1. CreateUserWizard控件
CreateUserWizard控件提供用于创建新网站用户帐户的用户界面。该对象与网站的用户数据存储区进行通信,以便在数据存储区中创建新用户帐户。默认情况下,CreateUserWizard 控件将接受网站访问者的用户名和密码。
在选定了CreateUserWizard控件之后,会自动创建一个登陆界面(这里用代码代替图形化操作)
// WebForm1.aspx <body> <form id="form1" runat="server"> <div> <asp:CreateUserWizard ID="CreateUserWizard1" runat="server"> <WizardSteps> <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> </asp:CreateUserWizardStep> <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> </asp:CompleteWizardStep> </WizardSteps> </asp:CreateUserWizard> </div> </form> </body>
自动生成如下界面
之后需要创建成员资格用户,用命令执行。打开“VS IDE的开发人员命令提示”(Developer Command Prompt for VS XXX),输入:
aspnet_regsql.exe
回车之后,出现如下安装向导对话框
一直下一步到以下界面,按照说明配置好之后下一步,完成
这时就创建好了一个成员资格数据库,连接SQL Server看看
嗯,数据库创建好了,这时切换回ASP.NET项目,打开Web.config,在其中加入connectionStrings配置节来配置数据库连接字符串,其中Server是服务器名,Database是数据库名,User Id是数据库登录账户,pwd是数据库登录密码
<configuration> <connectionStrings> <remove name="LocalServer"/> <add name="LocalServer" connectionString="Server=DEITIVOD\SQLEXPRESS; Database=aspnetdb; User Id=sa; pwd=admin"/> </connectionStrings> </configuration>
配置好后运行程序,测试结果如下图所示,需要注意的是,设置的密码必须包括字母、数字以及特殊字符且长度至少为7个字符,否则报错,例如123@qaz,tian_0ok
常见错误一,在没有配置jQuery的情况下会报WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping错误,因为Unobtrusive ValidationMode是.NET的一种隐式的验证方式,需要前端调用jquery来进行身份验证,且默认启用。
这时可以通过下面方法解决报错(所用的jQuery版本是截止2020年5月的最新版本):
在官网下载jquery-3.5.1.js和jquery-3.5.1.min.js两个文件
在ASP项目的根目录下新建一个scripts文件夹,把jquery-3.5.1.js和jquery-3.5.1.min.js放进去
在根目录下添加全局应用程序类Global.asax文件,在Application_Start事件中添加如下代码:
protected void Application_Start(object sender, EventArgs e) { ScriptManager.ScriptResourceMapping.AddDefinition("jquery", new ScriptResourceDefinition { Path = "~/scripts/jquery-3.5.1.min.js", DebugPath = "~/scripts/jquery-3.5.1.js", CdnPath = "https://code.jquery.com/jquery-3.5.1.min.js", CdnDebugPath = "https://code.jquery.com/jquery-3.5.1.js" }); }
常见错误二,SQLExpress 数据库文件自动创建错误:
在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: SQL Network Interfaces, error: 26 - 定位指定的服务器/实例时出错)
说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
SQLExpress 数据库文件自动创建错误:
连接字符串使用应用程序 App_Data 目录中的数据库位置指定了一个本地 SQL Server Express 实例。由于提供程序确定应用程序服务数据库不存在,因此尝试自动创建该数据库。要成功检查应用程序服务数据库是否存在并自动创建应用程序服务数据库,必须满足下列配置要求:
1、如果应用程序在 Windows 7 或 Windows Server 2008 R2 上运行,则需要执行特殊配置步骤才能自动创建提供程序数据库。在以下地址提供了更多信息: http://go.microsoft.com/fwlink/?LinkId=160102。如果应用程序的 App_Data 目录尚不存在,则 Web 服务器帐户必须具有对应用程序目录的读写访问权限。这是必要的权限,因为如果不存在 App_Data 目录,Web 服务器帐户将自动创建它。
2、如果应用程序的 App_Data 目录已存在,则 Web 服务器帐户只要求对应用程序的 App_Data 目录具有读写访问权限。这是必要的权限,因为 Web 服务器帐户将尝试验证应用程序的 App_Data 目录中是否已存在 SQL Server Express 数据库。如果撤消 Web 服务器帐户对 App_Data 目录的读访问权限,提供程序便无法正确地确定 SQL Server Express 数据库是否已存在。如果提供程序尝试创建已存在的数据库的副本,则会出错。写访问权限也是必需的,因为创建新数据库时需要使用 Web 服务器帐户凭据。
3、计算机上必须安装 SQL Server Express。
4、Web 服务器帐户的进程标识必须具有本地用户配置文件。有关如何为计算机帐户和域帐户创建本地用户配置文件的详细信息,请参见自述文档。
这是因为CreateUserWizard控件默认连接SQL Express数据库,此时需要下载安装SQL Express数据库并重复以上建立数据库及以后的步骤。
如果想以SQL Server 数据库继续执行程序,可以参考博客WebPart应用程序中服务器错误的解决办法,对连接字符串进行配置
2.2. Login控件
Login控件是一个复合控件,它有效集成了登录验证页面中常见的用户界面元素和功能,该控件是与CreateUserWizard控件相互联动的,必须要先注册用户才能登录。
例如下面的代码,构造了一个Login控件,在登录成功时跳转到页面WebForm2.aspx
// .aspx文件 <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" DestinationPageUrl="~/WebForm2.aspx"></asp:Login> </div> </form> </body>
2.3. LoginName控件
LoginName控件显示用户的登录名,如果应用程序使用Windows身份验证,该控件则显示用户的域名和账户名:如果应用程序使用Forms身份验证,则显示数据库中Membership的账号,通常使用Forms身份验证。
例如在已经放置了Login控件的基础上,放置一个LoginName控件:
// WebForm2.aspx文件 <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" DestinationPageUrl="~/WebForm3.aspx"></asp:Login> </div> </form> </body> // WebForm3.aspx文件 <body> <form id="form1" runat="server"> <div> <asp:LoginName ID="LoginName1" runat="server" FormatString="欢迎您:{0}" /> </div> </form> </body>
如果出现LoginName中用户名不显示或者显示的是计算机的名字,而不是网站用户的名字,则需要在Web.config中的
<system.web> 配置节中配置 < authentication> 节,如下: <system.web> <!-- 其他配置节 --> <authentication mode="Forms"> <!-- loginUrl中填写Login控件在的页面 --> <forms loginUrl="~/WebForm2.aspx" timeout="2880" /> </authentication> </system.web>
2.4. LoginStatus控件
LoginStatus控件用来描述用户的登录状态,它可以表示两种状态"已登录网站"和"已从网站注销",对于上述任何一种或两种状态,都可以为其显示文本或图像。
例如下面的代码:
// WebForm4.aspx <body> <form id="form1" runat="server"> <div> <asp:LoginName ID="LoginName1" runat="server" FormatString="{0}" /> <asp:LoginStatus ID="LoginStatus1" runat="server" /> </div> </form> </body> // WebForm2.aspx <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" DestinationPageUrl="~/WebForm4.aspx"></asp:Login> </div> </form> </body>
2.5. LoginView控件
LoginView控件根据用户是否经过身份验证以及属于哪个网站角色(如果用户经过身份验证),为不同的用户显示不同的网站内容模板或视图。
例如下面的代码,就是用LoginView控件包含了LoginName控件和LoginStatus控件对登录信息进行展示
// WebForm2.aspx <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" DestinationPageUrl="~/WebForm4.aspx"></asp:Login> </div> </form> </body> // WebForm4.aspx <body> <form id="form1" runat="server"> <div> <asp:LoginView ID="LoginView1" runat="server"> <AnonymousTemplate> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/WebForm2.aspx">请您登录本网站</asp:HyperLink> </AnonymousTemplate> <LoggedInTemplate> <asp:LoginName ID="LoginName1" runat="server" FormatString="欢迎您:{0}" /> <br /> <asp:LoginStatus ID="LoginStatus1" runat="server" /> </LoggedInTemplate> </asp:LoginView> </div> </form> </body>
2.6. ChangePassword控件
ChangePassword控件可实现快速修改密码。
如下代码使用了ChangePassword控件修改已登录用户的密码:
// WebForm2.aspx <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" DestinationPageUrl="~/WebForm5.aspx"></asp:Login> </div> </form> </body> // WebForm5.aspx <body> <form id="form1" runat="server"> <div> <asp:ChangePassword ID="ChangePassword1" runat="server"></asp:ChangePassword> </div> </form> </body>
也可以选择指定ChangePassword控件的SuccessPageUrl为登录页面,这样在成功修改密码后就会自动跳转的登录界面要求用户重新登录,例如在本例中,可以将WebForm5.aspx修改为
<body> <form id="form1" runat="server"> <div> <asp:ChangePassword ID="ChangePassword1" runat="server" SuccessPageUrl="~/WebForm2.aspx"></asp:ChangePassword> </div> </form> </body>