利用Asp.Net的Identity控制登录权限

一直对Asp.Net的MVC中的AuthorizeAttribute控制登录感到很困惑,这几天研究了一下,大概了解了一下整个流程,写出来记录一下。

场景:1.即使没有登录,也可以访问一些可以匿名访问的Action。

   2.对于登录来说,如果在某个地方登录成功,那么在缓存没清除或者过期之前,下次再进入该系统的话,正常情况是不需要再次登录的。

     3.对于需要登录的Action,如果匿名请求,那么需要跳转到登录页面。

 

如以下流程图:

 

这张流程图只是大概描述了一下登录的过程。还有其他的细节,暂不考虑。

 

再说一下AuthorizeAttribute的验证原理:

验证登录的机制,无非是根据请求的数据判断用户是否已经登录。AuthorizeAttribute进行权限判断的依据是如果登录成功在浏览器中设置加密Cookie,每次发送请求都把Cookie发送回服务器进行验证。

我根据自己的理解。画了如下流程图。

下面只列出部分关键代码:

1.创建User类,继承自Microsoft.AspNet.Identity.IUser,实现UserName属性。

   public class User : IUser
    {
        public User(List<string> tels, List<string> mails, string password)
        {
            Id = Guid.NewGuid().ToString("N");
            Tels = tels;
            Mails = mails;
            Password = password;
        }

        public string Id { get; set; }

        public string Password { get; set; }

        public string Name { get; set; }

        public string Address { get; set; }

        public List<string> Tels { get; set; }

        public List<string> Mails { get; set; }

        public string Company { get; set; }

        public string Job { get; set; }

        public string Image { get; set; }


        public string UserName
        {
            get
            {
                return Name;
            }
            set
            {
                Name = value;
            }
        }
    }
User

 

2.创建了IUserService接口,继承自Microsoft.AspNet.Identity.IUserStore<User>;;

    public interface IUserService : IUserStore<User>
    {
        bool RegisterByTel(string tel, string pwd);

        bool RegisterByMail(string mail, string pwd);

        bool LoginByTel(User user);

        bool LoginByMail(string mail, string pwd);

        bool UpdateUser(LinkMan linkMan);

        bool LoginByMail(User user);
    }
IUserService

 

3.创建自定义验证其,继承自AuthorizeAttribute,并且添加到全局过滤:

  public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new MyAuthorizeAttribute());
        }
    }

    public class MyAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated) // 未登录
            {
                var attr = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true);
                bool allowAnonymous = attr.Any(a => a != null);
                if (allowAnonymous)
                    return;

                var identityName = filterContext.HttpContext.User.Identity.Name;
                if (string.IsNullOrEmpty(identityName))
                {
                    filterContext.Result = new RedirectResult("/Default/Login/Index");
                }
            }
            base.OnAuthorization(filterContext);
        }
    }
FilterConfig

该过滤器,只是简单的过滤器,没太复杂的业务逻辑。

 

4.在登录成功后,设置标记。

   user.UserName = telOrMail;
                var identity = new Microsoft.AspNet.Identity.UserManager<User>(ServiceFactory.NewUserService()).CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie).Result;
                HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
         
LoginSuccess

这里只列出了关键代码,没列出登录的所有代码,

 

 

以上的这些步骤就实现了所列出的3个场景。

posted @ 2018-01-16 18:54  冲破天窗  阅读(351)  评论(0编辑  收藏  举报