编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> ASP.NET -> ASP.NET MVC View 和 Web API 的基本权限验证 -> 正文阅读

[ASP.NET]ASP.NET MVC View 和 Web API 的基本权限验证

ASP.NET MVC 5.0已经发布一段时间了,适应了一段时间,准备把原来的MVC项目重构了一遍,先把基本权限验证这块记录一下。
环境:Windows 7 Professional SP1 + Microsoft Visual Studio 2013(MVC 5 + Web API 2)
修改Web.config,增加Forms验证模式,在system.web节点中增加以下配置:

<authentication mode="Forms">
  <forms loginUrl="~/login" defaultUrl="~/" protection="All" timeout="20" name="__auth" />
</authentication>

【MVC View Controller 篇】
新建一个PageAuth,继承自AuthorizeAttribute:

using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class PageAuth : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            return false;
        }

        if (httpContext.User.Identity.IsAuthenticated && base.AuthorizeCore(httpContext))
        {
            return ValidateUser();
        }

        httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
        return false;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (filterContext.HttpContext.Response.StatusCode == (int)HttpStatusCode.Forbidden)
        {
            filterContext.Result = new RedirectToRouteResult("AccessErrorPage", null);
        }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl);
    }

    private bool ValidateUser()
    {
        //TODO: 权限验证
        return true;
    }
}

建一个Controller的基类PageBase,继承自Controller:

using System.Web.Mvc;


[PageAuth]
public class PageBase : Controller
{
}

所有View的Controller均继承自PageBase,不再继承自Controller。
继承PageBase之后,所有的Controller均需登录,给允许匿名访问的Controller(或Action)增加AllowAnonymous(以AccountController为例):

using System.Web.Mvc;


public class AccountController : PageBase
{
    [AllowAnonymous]
    public ActionResult Login()  // 可匿名访问
    {
        ViewBag.Title = "用户登录";
        return View();
    }

    public ActionResult Detail(int id)   // 需登录访问
    {
        ViewBag.Title = "用户详情";
        return View();
    }
}

页面Controller的开发,基本结束,接下来就是在登录页面(~/login)使用js提交登录信息,用post方式提交。
提交之后,需要开发Web API的接口了。
【MVC Web API Controller 篇】
同样,新建一个ApiAuth,继承自ActionFilterAttribute:

using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Security;


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class ApiAuth : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        try
        {
            if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0)   // 允许匿名访问
            {
                base.OnActionExecuting(actionContext);
                return;
            }

            var cookie = actionContext.Request.Headers.GetCookies();
            if (cookie == null || cookie.Count < 1)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
                return;
            }

            FormsAuthenticationTicket ticket = null;

            foreach (var perCookie in cookie[0].Cookies)
            {
                if (perCookie.Name == FormsAuthentication.FormsCookieName)
                {
                    ticket = FormsAuthentication.Decrypt(perCookie.Value);
                    break;
                }
            }

            if (ticket == null)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
                return;
            }

            // TODO: 添加其它验证方法

            base.OnActionExecuting(actionContext);
        }
        catch
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
        }
    }
}

新建一个ApiController的基类ApiBase,继承自ApiController:

using System.Web.Http;


[ApiAuth]
public class ApiBase : ApiController
{
}

所有API的Controller均继承自ApiBase,不再继承自ApiController。
继承ApiBase之后,给允许匿名访问的Controller(或Action)增加AllowAnonymous(以LoginController为例):

using System.Web.Http;
using System.Web.Security;


public class LoginController : ApiBase
{
    [HttpPost]
    [AllowAnonymous]
    public bool Login([FromBody]LoginInfo loginInfo)
    {
        try
        {
            var cookie = FormsAuthentication.GetAuthCookie("Username", false);
            var ticket = FormsAuthentication.Decrypt(cookie.Value);
            var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, "");
            cookie.Value = FormsAuthentication.Encrypt(newTicket);
            DeyiContext.Response.Cookies.Add(cookie);return true;
        }
        catch
        {
            return false;
        }
    }
}

【写在最后】
网上查了很多方法,还需要时间验证一下各个方法的合理度。
关于Web API的安全性,个人觉得,还是采用SSL的方式更加稳妥一些。
另外,网上很多写的在Web API的权限判断的时候,使用的是actionContext.Request.Headers.Authorization来判断,如下:

if (actionContext.Request.Headers.Authorization == null)
{
    // 判断是否允许匿名访问
}
else
{
    var ticket = FormsAuthentication.Decrypt(actionContext.Request.Headers.Authorization.Parameter);
    // 后续其它验证操作
}

还没有完成测试该方法,慢慢来吧~~~
  ASP.NET 最新文章
IIS服务器的请求流程
通过Web Service实现IP地址查询功能
VS 远程调试阿里云上的web站点,Remote Deb
sqlserver的四种分页方式
WebService服务(转)
C#去除字符串中的反斜杠
拦截asp.net输出流做处理
性能优化系列
C# 生成表格代碼
微信公众平台入门开发教程.Net(C#)框架
上一篇文章      下一篇文章      查看所有文章
加:2015-03-29 21:55:25  更:2017-05-14 07:18:07 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年11日历
2019-11-12 12:36:49
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识