ASP.NET WP - 安全性

在本章中,我们将介绍如何保护网站,以便某些网页仅供登录的用户使用.为了保护您的网站,您可以建立您的网站以便用户可以登录.保护您的网站有很多原因.

  • 您的网站可能只有成员可以使用的网页.

  • 有时您需要用户登录才能发送反馈或在您的网站上发表评论.

  • 如果用户没有登录,那么他们仍然可以浏览一些页面,但不能浏览所有页面.

  • 用户未登录称为匿名用户.

如何通过身份验证保护网站?

用户首先需要在您的网站上注册,然后才能登录该网站.要在网站上注册,用户需要用户名和电子邮件地址以及密码来确认用户是他们声称的用户.登录和确认用户身份的过程称为身份验证.

WebMatrix 提供内置模板,称为 Starter Site 创建一个包含以下属性的网站.

  • 可以存储的数据库用户的用户名和密码.

  • 用户可以注册的注册页面.

  • 登录/退出页面.

  • 密码恢复和重置页面.

让我们通过创建一个新的Starter Site来看一个简单的例子.

网站来自模板

在"站点名称"字段中输入 SecurityDemo ,然后单击"下一步".这将安装和配置所需的软件包.

安装完成后,让我们运行应用程序,您将看到以下网页.

主页

如您所见,有两个按钮注册登录页面右上角的.

点击注册链接,您将看到以下网页:您可以通过提供以下信息进行注册.

注册

这是实现 Register.cshtml 文件,该文件位于网站上的帐户文件夹下.

@ *如果您使用捆绑,请删除此部分* @

@section Scripts {
   <script src = "~/Scripts/jquery.validate.min.js"></script>
   <script src = "~/Scripts/jquery.validate.unobtrusive.min.js"></script>
}
@{
   Layout = "~/_SiteLayout.cshtml";
   Page.Title = "Register";
   
   // Initialize general page variables
   var email = "";
   var password = "";
   var confirmPassword = "";
   
   // Setup validation
   Validation.RequireField("email", "You must specify an email address.");
   Validation.RequireField("password", "Password cannot be blank.");
   Validation.Add("confirmPassword",
   Validator.EqualsTo("password", "Password and confirmation password do not match."));
   Validation.Add("password",
      Validator.StringLength(
         maxLength: Int32.MaxValue,
         minLength: 6,
         errorMessage: "Password must be at least 6 characters"));
   
   // If this is a POST request, validate and process data
   if (IsPost) {
      AntiForgery.Validate();
      email = Request.Form["email"];
      password = Request.Form["password"];
      confirmPassword = Request.Form["confirmPassword"];
      
      // Validate the user's captcha answer
      // if (!ReCaptcha.Validate("PRIVATE_KEY")) {
         // ModelState.AddError("recaptcha", "Captcha response was not correct");
      // }
     
      // If all information is valid, create a new account
      if (Validation.IsValid()) {
         // Insert a new user into the database
         var db = Database.Open("StarterSite");
         
         // Check if user already exists
         var user = db.QuerySingle("SELECT Email FROM UserProfile WHERE LOWER(Email) =
            LOWER(@0)", email);
         
         if (user == null) {
            // Insert email into the profile table
            db.Execute("INSERT INTO UserProfile (Email) VALUES (@0)", email);
            // Create and associate a new entry in the membership database.
            // If successful, continue processing the request
            
            try {
               bool requireEmailConfirmation = !WebMail.SmtpServer.IsEmpty();
               var token = WebSecurity.CreateAccount(email, password, 
                  requireEmailConfirmation);
               
               if (requireEmailConfirmation) {
                  var hostUrl = Request.Url.GetComponents(UriComponents.SchemeAndServer,
                     UriFormat.Unescaped);
                  var confirmationUrl = hostUrl + VirtualPathUtility.ToAbsolute
                     ("~/Account/Confirm?confirmationCode = " 
                     + HttpUtility.UrlEncode(token));
                  WebMail.Send(
                     to: email,
                     subject: "Please confirm your account",
                     body: "Your confirmation code is: " + token + ". 
                     Visit <a href = " + confirmationUrl + ">" + 
                     confirmationUrl + "</a> to activate your account."
                  );
               }
               
               if (requireEmailConfirmation) {
                  // Thank the user for registering and let them know an 
                     email is on its way
                  Response.Redirect("~/Account/Thanks");
               } else {
                  // Navigate back to the homepage and exit
                  WebSecurity.Login(email, password);
                  Response.Redirect("~/");
               }
            }catch (System.Web.Security.MembershipCreateUserException e) {
               ModelState.AddFormError(e.Message);
            }
         } else {
            // User already exists
            ModelState.AddFormError("Email address is already in use.");
         }
      }
   }
}

<hgroup class = "title">
   <h1>@Page.Title.</h1>
   <h2>Create a new account.</h2>
</hgroup>

<form method = "post">
   @AntiForgery.GetHtml()
   @* If at least one validation error exists, notify the user *@
   @Html.ValidationSummary("Account creation was unsuccessful. 
      Please correct the errors and try again.", 
      excludeFieldErrors: true, htmlAttributes: null)
   
   <fieldset>
      <legend>Registration Form</legend>
      <ol>
         <li class = "email">
            <label for = "email" @if(!ModelState.IsValidField("email")){
               <text>class = "error-label"</text>}>Email address</label>
            <input type = "text" id = "email" name = "email" value = "@email"   
               @Validation.For("email") />
            
            @* Write any email validation errors to the page *@
            @Html.ValidationMessage("email")
         </li>
         
         <li class = "password">
            <label for = "password" @if(!ModelState.IsValidField("password")) {<text>
               class = "error-label"</text>}>Password</label>
            <input type = "password" id = "password" name = "password"
               @Validation.For("password") />
            
            @* Write any password validation errors to the page *@
            @Html.ValidationMessage("password")
         </li>
         
         <li class = "confirm-password">
            <label for = "confirmPassword" 
               @if(!ModelState.IsValidField("confirmPassword")) 
               {<text>class = "error-label"</text>}>Confirm password</label>
            <input type = "password" id = "confirmPassword" name = "confirmPassword"
               @Validation.For("confirmPassword") />
            
            @* Write any password validation errors to the page *@
            @Html.ValidationMessage("confirmPassword")
         </li>
         
         <li class = "recaptcha">
            <div class = "message-info">
               <p>
                  To enable CAPTCHA verification, <a href = 
                  "http://go.microsoft.com/fwlink/?LinkId=204140">install the
                  ASP.NET Web Helpers Library</a> and uncomment ReCaptcha.GetHtml 
                  and replace 'PUBLIC_KEY' with your public key. At the top of this 
                  page, uncomment ReCaptcha. Validate and replace 'PRIVATE_KEY' with 
                  your private key.Register for reCAPTCHA keys at <a href = 
                  "http://recaptcha.net"> reCAPTCHA.net</a>.
               </p>
            </div>
            @*
               @ReCaptcha.GetHtml("PUBLIC_KEY", theme: "white")
               @Html.ValidationMessage("recaptcha")
            *@
         </li>
      </ol>
      <input type = "submit" value = "Register" />
      
   </fieldset>
</form>

当您单击"注册"按钮时,您将再次看到"主页",但现在您将看到通过提及您的电子邮件ID登录.

Logo

仅为会员创建页面

在网站中,您需要一些只能由成员访问的页面. ASP.NET允许您配置页面,以便只有登录成员才能访问它们.通常情况下,如果匿名用户尝试访问仅限会员的页面,则会将其重定向到登录页面.

让我们看一个简单的例子,我们在其中修改关于页面.当用户登录时,用户可以访问该页面,否则用户将被重定向到登录页面.所以让我们在 About.cshtml 文件中替换以下代码.

@if (!WebSecurity.IsAuthenticated) {
   Response.Redirect("~/Account/Login");
}
@{
   Layout = "~/_SiteLayout.cshtml";
   Page.Title = "About My Site";
}

<hgroup class = "title">
   <h1>@Page.Title.</h1>
   <h2>Your app description page.</h2>
</hgroup>

<article>
   <p>Use this area to provide additional information.</p>
   <p>Use this area to provide additional information.</p>
   <p>Use this area to provide additional information.</p>
</article>

<aside>
   <h3>Aside Title</h3>
   <p>Use this area to provide additional information.</p>
   
   <ul>
      <li><a href = "~/">Home</a></li>
      <li><a href = "~/About">About</a></li>
      <li><a href = "~/Contact">Contact</a></li>
   </ul>

</aside>

让我们运行应用程序,您将看到以下主页.

登录页面

用户目前尚未登录,因此当您点击"关于"链接时,您将看到您将被定向到登录页面如以下屏幕截图所示.

使用本地帐户

让我们输入凭证.

登录本地帐户

现在点击登录,您将看到主页.

现在点击"关于"链接,您将看到现在可以访问"关于"页面,如下所示截图.

关于我的网站