zoukankan      html  css  js  c++  java
  • [转]mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理

    本文转自:http://www.cnblogs.com/shootingstar/p/5629668.html

    1.mvc5+ef6+Bootstrap 项目心得--创立之初

    2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理

    3.mvc5+ef6+Bootstrap 项目心得--WebGrid

    最近和朋友完成了一个大单子架构是mvc5+ef6+Bootstrap,用的是vs2015,数据库是sql server2014。朋友做的架构,项目完成后觉得很多值得我学习,在这里总结下一些心得。先说明,以下方法是创建项目时选择MVC,而不是Empty。所以有许多多余的东西,如果选择Empty创建项目,请看目录1

    创建项目一开始删掉App_Start目录下的IdentityConfig.cs和Startup.Auth.cs文件;清空Modle文件夹,Controller文件夹和相应的View; 删除目录下的ApplicationInsights.config文件和Startup.cs文件。(不使用自带的Identity,太多内容不需要)

    修改web.config文件(添加<add key="owin:AutomaticAppStartup" value="false"/>不使用Startup.cs文件来启动项目)

    复制代码
    <appSettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
        <add key="owin:AutomaticAppStartup" value="false"/> <!--去掉创建项目初的Startup.cs文件的设置-->
      </appSettings>
    复制代码
    <modules>
          <remove name="FormsAuthentication"/>
        </modules>
    这句在web.config里面必须去掉,不然User.Identity不起作用

    (不用他们是因为自带的这些内容太冗余)

    1.首先介绍数据库这一块,数据库我们是配置的可以使用NuGet命令手动生成和修改的。在项目目录想创建Migrations文件夹,里面添加Configuration.cs文件

    复制代码
    internal sealed class Configuration : DbMigrationsConfiguration<AccountContext>
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = true;
                ContextKey = "UserProject.DAL.AccountContext";
            }
            protected override void Seed(AccountContext context)
            {
                //base.Seed(context);
            }
        }
    复制代码

    在Model文件夹下添加AccountContext.cs文件

    复制代码
    public class AccountContext:DbContext
        {
            public AccountContext():base("AccountContext") {
    
            }
    
            public DbSet<User> Users { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    复制代码
    <connectionStrings>
        <add name="AccountContext" connectionString="Data Source=(LocalDb)MSSQLLocalDB;AttachDbFilename=|DataDirectory|UserProject.mdf;Initial Catalog=UserProject;Integrated Security=True" providerName="System.Data.SqlClient" />
      </connectionStrings>

    然后 使用vs2015里面的工具-NuGet包管理器-程序包管理控制平台

    输入add-migration Initial 按回车,在输入update-database按回车。在App_Data文件夹下就会看到AccountContext数据库了。

    2.创建测试用的Model

    在Model文件夹下添加User.css文件

    复制代码
    public class User
        {
            public int ID { get; set; }
            public string UserName { get; set; }
            public string Password { get; set; }
            public Role Role { get; set; }
        }
    复制代码
    public enum Role//角色枚举
    { 管理员 = 1, 员工 = 2, 经理 = 3, 总经理 = 4, 董事长 = 5 }

    在ViewModel文件夹中添加Account.cs文件

    复制代码
    public class Account
        {
            [Required]
            public string Name { get; set; }
            [Required]
            public string Password { get; set; }
    
            public string RePassword { get; set; }
        }
    复制代码

    3.创建测试用到的Controller

    这里推荐创建BaseController,之后的Controller就继承它来使用

    复制代码
    public class BaseController : Controller
        {
            public string UserName => User.Identity.Name;
            public AccountContext db = new AccountContext();
            private User _userInfo = null;
            public User CurrentUserInfo
            {
                get
                {
                    if (_userInfo == null)
                    {
                        var user = db.Users.SingleOrDefault(u => u.UserName == UserName);//此处为了不每次访问用户表可以做一个静态类,里面存放用户表信息.
                        _userInfo = user == null ? null : new User()
                        {
                            ID = user.ID,
                            UserName = user.UserName,
                            Role = user.Role
                        };
                    }
                    return _userInfo;
                }
            }     //验证角色:获取Action的CustomAttributes,过滤角色
            protected override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                base.OnActionExecuting(filterContext);
                var authRoleAtt = filterContext.ActionDescriptor.GetCustomAttributes(false).SingleOrDefault(att => att is AuthorizeRoleAttribute) as AuthorizeRoleAttribute;
                if (authRoleAtt == null && CurrentUserInfo != null)
                    return;
    
                if (!authRoleAtt.Roles.Contains(CurrentUserInfo.Role))
                {
                    filterContext.Result = View("NoPermission", "_Layout", "您没有权限访问此功能!");
                }
            } //这里是记log用
            protected override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                base.OnActionExecuted(filterContext);
                var msg = $"用户: {CurrentUserInfo?.UserName}, 链接: {Request.Url}";
                if (Request.HttpMethod == "POST")
                    msg += $", 数据: {HttpUtility.UrlDecode(Request.Form.ToString())}";
                //Log.Debug(msg);
            }
        }
    复制代码
    复制代码
    public class AuthorizeRoleAttribute : Attribute
        {
            public List<Role> Roles { get; set; }
            public AuthorizeRoleAttribute(params Role[] roles)
            {
                Roles = new List<Role>(roles);
            }
        }
    复制代码

    AdminController继承BaseController

    复制代码
    [Authorize]
            public ActionResult Index()
            {
                return View(db.Users.ToList());
            }
    
            
            [Authorize, AuthorizeRole(Role.管理员)]
            public ActionResult Details(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                User user = db.Users.Find(id);
                if (user == null)
                {
                    return HttpNotFound();
                }
                return View(user);
            }
    复制代码

     4.创建Action和VIew

    登录页面:

    复制代码
    @model UserProject.ViewModels.Account
    @{
        ViewBag.Title = "Login";
    }
    
    @using (Html.BeginForm("Login", "Admin",FormMethod.Post, new { @class = "form-horizontal", role = "form" })) {
        @Html.AntiForgeryToken()
        <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="登录" class="btn btn-primary" />
                        </div>
                    </div>
    }
    复制代码

    登录的Action:

    复制代码
    [AllowAnonymous]
            public ActionResult Login()
            {
    
                return View();
            }
    
            [HttpPost, AllowAnonymous]
            public ActionResult Login(Account model)
            {
                if (ModelState.IsValid)
                {
                    var user = db.Users.SingleOrDefault(t => t.UserName == model.Name && t.Password == model.Password);
                    if (user != null)
                    {
                        FormsAuthentication.SetAuthCookie(model.Name, false);//将用户名放入Cookie中
    
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        ModelState.AddModelError("Name", "用户名不存在!");
                    }
                }
                return View(model);
            }
    
            public ActionResult LogOff()
            {
                FormsAuthentication.SignOut();
                return RedirectToAction("Login");
            }
    复制代码

    通过以上方式就完成了用户的登录和权限的控制, 访问Details这个Action的时候必须是管理员角色。

    如果需要多个角色使用Action可以:[Authorize, AuthorizeRole(Role.管理员,Role.经理)]

    使用此方法登录的用户保存在Cookie里面 :FormsAuthentication.SetAuthCookie(model.Name, false);
    在Controller和View里面直接使用User.Identity得到用户名
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/freeliver54/p/6427486.html
Copyright © 2011-2022 走看看