MVC之认证与授权(1)

用户身份认证是web应用程序中常见的功能,只有特定的用户才能访问资源,不允许匿名访问,也就是在未登录的状态下进行访问,那么就需要验证用户的身份,以及做出相应的处理。
在这里插入图片描述
当web应用程序接收到用户的请求,服务器端将试图去认证用户
授权:
校验已认证的用户是否有权限访问请求的资源

认证的方式:
在这里插入图片描述
实现认证的方法:
在这里插入图片描述
本案例使用VS2017进行测试开发。
1.首先创建MVC项目,然后在App_Data文件下添加数据库db(便捷方式):
App_Data文件–>右键–>新建项

在这里插入图片描述
添加数据表user:
在这里插入图片描述
添加测试数据即可

2.在Models文件夹中,使用EF设计工具由数据库生成数据模型类(DBFirst模式):
在这里插入图片描述
3.添加Account控制器:
处理用户的注册、登录、以及退出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AuthenticationDemo.Models;
using System.Web.Security;

namespace AuthenticationDemo.Controllers
{
    public class AccountController : Controller
    {
        dbEntities db = new dbEntities();
        // GET: Account

        /// <summary>
        /// Signup页面初始化
        /// </summary>
        /// <returns></returns>
        public ActionResult Signup()
        {
            return View();
        }

        /// <summary>
        /// 接收表单提交
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Signup(user u)
        {
            if(ModelState.IsValid)//检测表单验证是否已通过
            {
                db.users.Add(u);//添加用户
                if(db.SaveChanges()>0)//持久化操作,提交到数据库
                {
                    return RedirectToAction("Login");//重定向到Login动作方法
                }
            }
            return View();
        }

        /// <summary>
        /// 登录页面初始化
        /// </summary>
        /// <returns></returns>
        public ActionResult Login()
        {
            return View();
        }

        /// <summary>
        /// 登录页面表单提交
        /// </summary>
        /// <param name="u"></param>
        /// <param name="ReturnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Login(user u,string ReturnUrl)
        {
            if (ModelState.IsValid)//检测表单是否已验证通过
            {
                var user = db.users.Where(x => x.username == u.username && x.password == u.password).FirstOrDefault();
                if(user!=null)//检查用户是否存在
                {
                    FormsAuthentication.SetAuthCookie(u.username, false);//为用户创建一个身份凭证,用来标识用户
                    Session["uname"] = u.username.ToString();//将用户名保存到Session中(可用户标识所处于的状态(已登录/未登录))
                    if (ReturnUrl != null)
                    {
                        return Redirect(ReturnUrl);
                    }
                    else
                    {
                        return Redirect("/Home/Service");
                    }
                }
            }

            return View();
        }

        /// <summary>
        /// 退出登录状态
        /// </summary>
        /// <returns></returns>
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();//删除身份凭证
            Session["uname"] = null;//删除session值
            return Redirect("Login");//重定向到Login页面
        }
    }
}

添加SignUp注册页面:

@model AuthenticationDemo.Models.user
@{
    ViewBag.Title = "Signup";
}
<h2>Signup</h2>
@using (Html.BeginForm("Signup", "Account"))
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>user</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.username, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.username, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.username, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.password, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.password, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.password, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Signup" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Login", "Login")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

添加Login登录页面:

@model AuthenticationDemo.Models.user
@{
    ViewBag.Title = "Login";
}
<h2>Login</h2>
@using (Html.BeginForm("Login","Account",FormMethod.Post)) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>user</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.username, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.username, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.username, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.password, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.password, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.password, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Login" class="btn btn-default" />
            </div>
        </div>
    </div>
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

4.添加Home控制器:
添加 Index、About、Service动作方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AuthenticationDemo.Models;
namespace AuthenticationDemo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public ActionResult Service()
        {
            return View();
        }
    }
}

对应的Index视图:

@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<div class="breadcrumb">
    <h3>This is MVC APP</h3>
    <p>We are Learning Authentication</p>
</div>

About视图:

@{
    ViewBag.Title = "About";
}
<h2>This is About View</h2>

Services视图:

@{
    ViewBag.Title = "Service";
}
<h2>Service</h2>
<ul>
    <li>Web Development</li>
    <li>Web SEO</li>
    <li>Web Designing</li>
    <li>Logo Designing</li>
</ul>

实现认证过滤器:
在这里插入图片描述
在这里插入图片描述
在System.Web.Mvc命名空间下提供了一些以Attribute为结尾的注解属性类
AuthorizeAttribute类:
指定对控制器或操作方法的访问仅限于满足授权要求的用户。
5.在Home控制器的Service动作方法上,添加Authorize属性:

[Authorize]
public ActionResult Service()
{
    return View();
}

运行并访问Service页面:显示无权访问
在这里插入图片描述
如果无权访问,应引导进行登录–>告诉MVC如果匿名访问,应先跳转到登录页面.
解决方案:
在Web.config配置文件中,配置认证节点:
forms authentication
此节点对应的是System.Web.Security命名空间下的FormsAuthentication类,提供了关于forms认证方式的信息

 <system.web>
    <!--配置authentication节点:拒绝匿名用户访问(相对于整个Web应用程序)
      loginUrl:用户如果没有登录,则跳转到登录页面
    -->
	<authentication mode="Forms">
      <forms loginUrl="~/Account/Login"></forms>
    </authentication>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
  </system.web>

在View前台页面,根据Session中的key对应的value是否为空,控制内容的显示/隐藏:

@*检测用户是否已登录*@
@if (Session["uname"] != null)
{
<li><a href="">Dear @Session["uname"]</a></li>
<li>@Html.ActionLink("Logout", "Logout", "Account")</li>
}
else
{
<li>@Html.ActionLink("Login", "Login", "Account")</li>
}

添加退出登录的功能:
在Account控制器中,添加Logout动作方法:

/// <summary>
/// 退出登录状态
/// </summary>
/// <returns></returns>
public ActionResult Logout()
{
   FormsAuthentication.SignOut();//删除身份凭证
   Session["uname"] = null;//删除session值
   return Redirect("Login");//重定向到Login页面
}

Home控制器:

	[Authorize]  //强制要进行身份验证(拒绝进行匿名访问)---控制器中的所有方法都需要认证
    public class HomeController : Controller
    {
        dbEntities db = new dbEntities();
        // GET: Home
        [AllowAnonymous] //允许进行匿名访问
        public ActionResult Index()
        {
            return View();
        }

        //[Authorize]
        public ActionResult Service()
        {
            return View();
        }
    }

全局的认证过滤器:
在整个Web应用程序中,任何地方的调用都需要先进行认证
在Global.asax全局文件中:添加以下代码即可

GlobalFilters.Filters.Add(new AuthorizeAttribute());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值