参考 :

http://hi.baidu.com/iykqqlpugocfnqe/item/e132329bdea22acbb6253105  ASP.NET中处理请求的流程图

http://www.cnblogs.com/yao/archive/2006/06/24/434783.html

http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html#_label3

这篇主要说说实现和逻辑流程.

所谓认证和授权是指对一个服务器资源的访问限制管理。

比如有一些文件是不公开的,只有管理人员能访问的到,这要求他们必须先"登入"。这就是认证

那么授权是在认证之后发生的事情,管理人员也有分等级,好比公司有些机密文件只有上层可以看。这就是授权.

认证和授权微软已经为我们做了很多封装,form 认证就是其中一种。

不过,这里我们先想想,在原始年代,我们要如何去实现呢?

我们都知道web所有资源都是通过http请求来访问的。显然第一步是拦截所有不公开的资源.

第二步就是检查他们是否"登入".

所谓的"登入"其实就是通过一个 cookie 来完成的。

如果请求没有附带指定的 cookie 那么就表示没有登入,就该阻止访问 (并跳转到登入界面).

在登入页面确认用户密码后,给予cookie,就表示登入了啦 .

第三步

通过了认证,我们必须查看这个用户的身份(或者说角色), 比如是经理,主管,还是普通员工。

进一步的验证用户是否有足够的权限(授权)来访问这个资源。

好了,其实不太难。大至少就是这样了。

以上步骤涉及到2个重要的点 :

1. 如果拦截特定的资源请求 ?

2. cookie 的安全性

下面我来个一个微软封装好的例子, 一般上普通项目够用了。

1.在web config 加上一个 authentication

<system.web>
<authentication mode="Forms">
<forms loginUrl="~/login/Default.aspx" timeout="" defaultUrl="~/" />
</authentication>
</system.web>

这里用 mode 是 forms (我也只会这个)

loginUrl 是登入页面的路径 , timeout 是说cookie 的有效时间 , defaultUrl 我不清楚

2. 做一个登入页面,这里只是随便做。你明白就可以了

protected void Page_Load(object sender, EventArgs e)
{ }
protected void Button1_Click(object sender, EventArgs e) //登入
{
//set一个cookie , name and 是否要持久cookie,false的话会base on web config 的timeout
FormsAuthentication.SetAuthCookie("keatkeat", false);
}
protected void Button2_Click(object sender, EventArgs e) //注销
{
FormsAuthentication.SignOut();
}

3. 设定哪些文件路径需要拦截认证

  <configuration>
<location path="securityFolder">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
</configuration>

path 指定路径,其下的所有folders files 都被限制了.

authorization 内的元素 有多种配搭模式

<deny users="?">  基本上由 3 的东东做出来,

1. deny | allow (禁止 或者 允许)

2.users | roles | verbs ( users 用户 , roles 角色比较特别,后面我会教你如何设置一个或多个角色在一个user身上,verbs 就是http method ,GET POST 等)

3. ? | *  ( ? 代表匿名 , * 代表所有的)

所以上面这一句的解释是  -禁止匿名用户- (没登入就无法访问)

任何访问都是 users="*"  , 登入后就不再是 users="?"

完成以上的步骤基本上就可以做到一个简单的认证授权机制了(不需要分角色的话)

它验证的次序是这样的,如果pass了就不会继续验证了,所以一般上都是先写,deny 才写 allow

那么如果我们要高级一点的呢?

  <location path="securityFolder">
<system.web>
<authorization>
<allow roles="Admin,Boss"/>
<deny users="*"/>
</authorization>
</system.web>
</location>

允许角色为Admin或者Boss , 禁止所有用户

现在我们必须把用户的角色添加进用户里 (因为从上面开来,我们只给了个Name给用户)

class AuthenticateHttpModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(AuthenticateRequest);
}
private void AuthenticateRequest(object sender, EventArgs e)
{ HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context; //获取本次Http请求的HttpContext对象
if (ctx.User != null)
{
if (ctx.Request.IsAuthenticated == true) //验证过的一般用户才能进行角色验证
{
string name = ctx.User.Identity.Name; FormsIdentity fi = (System.Web.Security.FormsIdentity)ctx.User.Identity;
//FormsAuthenticationTicket ticket = fi.Ticket; //取得身份验证票
//string userData = ticket.UserData;//从UserData中恢复role信息
string[] roles = "Admin,zz".Split(','); //将角色数据转成字符串数组,得到相关的角色信息
ctx.User = new GenericPrincipal(fi, roles); //这样当前用户就拥有角色信息了
}
}
}
}

这里我们要写一个 HttpModule 来完成 (记得web config 也要添加哦)

我们用 new GenericPrincipal 来添加角色进用户里,这样就可以了。

注 : 我们这个模块是跑在微软后面的,所以我们完全不需要从cookie里面获取任何东西,直接用 context.User 就好了。

以上大概就是全部的过程了。

这里给一个自定义的例子 :

public class AdministratorIdentity : IIdentity
{
public string AuthenticationType { get; set; }
public string Name { get; set; }
public bool IsAuthenticated { get; set; }
} public class Administrator : IPrincipal
{
public IIdentity Identity { get; set; }
public string name { get; set; } //可以任意定义属性
public bool IsInRole(string role)
{
if (role == "Admin") //个种你想的到的验证手法都可以
{
return true;
}
return false;
}
}
if (ctx.Request.IsAuthenticated == true) //验证过的一般用户才能进行角色验证
{
string name = ctx.User.Identity.Name;
string type = ctx.User.Identity.AuthenticationType;
//自定义
ctx.User = new Administrator
{
name = "keatkeat",
Identity = new AdministratorIdentity {
AuthenticationType = ctx.User.Identity.AuthenticationType,
Name = "z",
IsAuthenticated = true
}
};
//原版添加 roles 的方式
//FormsIdentity fi = (System.Web.Security.FormsIdentity)ctx.User.Identity;
////FormsAuthenticationTicket ticket = fi.Ticket; //取得身份验证票
////string userData = ticket.UserData;//从UserData中恢复role信息
//string[] roles = "Admin".Split(','); //将角色数据转成字符串数组,得到相关的角色信息
//ctx.User = new GenericPrincipal(fi, roles); //这样当前用户就拥有角色信息了
}

这样到哪里只要 Ctx.User as Administrator 就可以容易的使用啦 ^^

这里也提一提使用 cookie 加密的安全性问题

第一,如果有人可以从你的电脑上获取到你的cookie , 那么他就等于拥有了你所有权限了。

第二,如果他没有入侵你的电脑,他是否可以自己创建一个加密的cookie来模拟你呢?

答案是不行,因为创建cookie时,加密是配合服务器的私钥的。(好像叫对称加密)

所以呢,基本上算是安全的。 参考 : http://blog.csdn.net/fancyf/article/details/348202

要自定义服务器的私钥的话可以这样写 :

<configuration>
<system.web>
<machineKey
validationKey="xxxxxxxxxxxxxxxxxxxxxxxx"
decryptionKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
validation="SHA1"
decryption="AES" />
</system.web>
</configuration>

好像也可以指定一个程序来输出 ,

machineKey 可以通过这个网站创建 http://www.a2zmenu.com/utility/Machine-Key-Generator.aspx#

下面我另外谈谈我的一些开发经验。

现今我们做的大部分是单页面应用,只有一个登入页面和一个主页面,其它的页面都是虚拟的。

如果是自己做 url rewrite 的话,要注意的是,请在 ResolveRequestCache(认证授权模块之后) 时才做.

以上的部分,如果你想自己实现也是完全可以的,cookie 的加密可以用微软的加密方法,你也可以继承 IPrincipal 来实现 自己的 User

也可以注册 HttpModule 拦截 AuthorizeRequest 比对路径,去sql 拿用户职位等等来做授权验证。

还有如果你用的是 WebAPI 的话,建议要把这2者分开。以上说的拦截是针对页面资源的访问。

WebAPI 内部也有拦截认证和授权的机制。所以针对 WebAPI 的资源还是用用 WebAPI 本身的机制来管理比较妥当.

WebAPI 是支持self host,但是如果我们是使用IIS又贪方便的话,我们也可以直接用上面的form认证。

所以的API请求依然会通过IIS的 pipe,到了API controller ,User 依然是我们的 context.User

如果遇到是 self host 的话,其实也可以用上面的概念来做。只不过不使用cookie 改成使用 http header 来替代。

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, loginName, DateTime.Now, DateTime.Now.AddDays(), true, data);
string cookieValue = FormsAuthentication.Encrypt(ticket);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookieValue);

这个加密解密做好其实原理依旧是通的啦。

总结 :

简单的说 认证与授权 ,不外乎就是  请求时附上身份,响应前验证身份。

ASP.NET 表单认证与角色授权的更多相关文章

  1. spring-security-4 (5)spring security Java配置实现自定义表单认证与授权

    前面三篇讲解了spring security的搭建以及简单的表单认证与授权原理.本篇将实现我们自定义的表单登录与认证.  本篇不会再讲项目的搭建过程,因为跟第二节的搭建如出一辙.本篇也不会将项目中所有 ...

  2. SharePoint 2013 表单认证使用ASP.Net配置工具添加用户

    前 言 上面一篇博客,我们了解到如何为SharePoint 2013配置表单身份认证,但是添加用户是一个麻烦事儿:其实,我们还可以用Asp.Net的配置工具,为SharePoint 2013添加表单用 ...

  3. SharePoint 2013 表单认证使用ASP.Net配置工具加入用户

    前 言 上面一篇博客,我们了解到怎样为SharePoint 2013配置表单身份认证.可是加入用户是一个麻烦事儿:事实上,我们还能够用Asp.Net的配置工具,为SharePoint 2013加入表单 ...

  4. Form authentication(表单认证)问题

    前言 最近在做ASP.NET MVC中表单认证时出了一些问题,特此记录. 问题 进行表单认证时,在 PostAuthenticateRequest 事件中从Cookie值中解密票据.如下: prote ...

  5. SharePoint 表单认证创建用户

    前言 本文介绍如何在SharePoint表单登陆中添加表单用户,前提是已经配置了表单认证,如果没配置表单登陆,需要先配置表单登陆: 1. 打开Visual Studio,如下图: 2. 新建一个项目 ...

  6. C#之Form表单认证

    原文地址: https://blog.csdn.net/chadcao/article/details/7859394 ASP.NET的安全认证,共有“Windows”.“Form”.“Passpor ...

  7. SharePoint 2013 修改表单认证登录页面

    前 言 之前的博客我们介绍了如何为SharePoint配置表单登陆,但是,登陆页面是丑.很丑.非常丑.特别非常丑!我们现在就介绍一下如何定制SharePoint表单登陆页面! SharePoint 表 ...

  8. ASP FORM表单提交判断

    ASP提交表单是先进行Form填写检测,检测完成没问题之后再执行写入数据库表操作. 相关源码: <script language="javascript"> funct ...

  9. php laravel加密 form表单认证 laravel分页

    use Illuminate\Support\Facades\Crypt; echo Crypt::encrypt(123); //加密echo "<br>";//解密 ...

随机推荐

  1. H1B工作签证紧俏 “中签率”低对中国留学生影响大-中新网

    H1B工作签证紧俏 "中签率"低对中国留学生影响大-中新网 H1B工作签证紧俏 "中签率"低对中国留学生影响大

  2. 【COM学习】之一、QueryInterface

    开始先说一句,学习com之前要学好c++ 对象模型. QueryInterface的使用: QueryInterface是IUnknown的一个成员函数,客户可以通过此函数来查询某个组件是否支持某个特 ...

  3. 【甘道夫】怎样在cdh5.2上执行mahout的itemcf on hadoop

    环境: hadoop-2.5.0-cdh5.2.0 mahout-0.9-cdh5.2.0 步骤: 基本思路是,将mahout下的全部jar包都引入hadoop的classpath就可以,所以改动了$ ...

  4. [置顶] vb报表的设计

    敲机房收费系统,最难的部分应该就是关于报表的部分了.相对于学生信息管理系统,报表是新内容,在vb中添加报表需要添加第三方控件,首先我们要下载水晶报表,下面就向大家展示一下我设计报表的步骤(我用的新版本 ...

  5. Robotium API -- click/clickLong操作

           click&clickLong方法(点击/长按事件)        ArrayList<android.widget.TextView> clickList(int ...

  6. Sort List (使用归并排序的链表排序)

    Sort a linked list in O(n log n) time using constant space complexity. C++代码的实现: #include<iostrea ...

  7. OpenStack对象存储——Swift

    OpenStack Object Storage(Swift)是OpenStack开源云计算项目的子项目之一,被称为对象存储,提供了强大的扩展性.冗余和持久性.本文将从架构.原理 和实践等几方面讲述S ...

  8. Myeclipse+Tomcat安装与配置

    一: Myeclipse安装很简单,没什么可说的,下面说一下怎么把英文版的Myeclipse汉化的问题 1.把汉化包解压,将解压后的“language”文件夹,放入Myeclipse\common文件 ...

  9. 在iptables和selinux中放行smb服务

    配置selinux [root@localhost samba]# getsebool -a | grep samba 查找selinux中对samba的限制项samba_domain_control ...

  10. E10后,导致VS2010调试时报错“未能将脚本调试器附加到计算机..."

    以管理员身份打开CMD,运行:regsvr32.exe "%ProgramFiles(x86)%\Common Files\Microsoft Shared\VS7Debug\msdbg2. ...