1. Owin

OWIN全名:Open Web Interface for .NET. 它是一个说明,而非一个框架,该声明用来实现Web服务器和框架的松耦合。它提供了模块化、轻量级和便携的设计。类似Node.js, WSGI.

Katana是微软实现的OWIN组件的集合。包含基础设施组件和功能性组件。并且暴露出了OWIN管道用来添加组件。可以在IIS、OwinHost.exe或者自定义的服务器中托管。

比如OWIN提供了新的登录模式,比如,打开Web.config文件,我们看到:

<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>

我们看到<authentication mode="None"/>,这里我们不在使用传统的Form认证,而是使用Owin的认证。我们打开Startup.cs文件,看到如下内容:

public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}

这里我们使用ConfigureAuth(app)来配置认证,打开这个方法的定义,可以看到如下方法:

public void ConfigureAuth(IAppBuilder app)
{
// 使应用程序可以使用 Cookie 来存储已登录用户的信息
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // 取消注释以下行可允许使用第三方登录提供程序登录
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: ""); //app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: ""); //app.UseFacebookAuthentication(
// appId: "",
// appSecret: ""); //app.UseGoogleAuthentication();
}

2. 本地认证Local Authentication

默认就是本地认证:

// 使应用程序可以使用 Cookie 来存储已登录用户的信息
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

3. 添加Facebook认证

// 取消注释以下行可允许使用第三方登录提供程序登录
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: ""); //app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: ""); //app.UseFacebookAuthentication(
// appId: "",
// appSecret: ""); //app.UseGoogleAuthentication();

取消注释对应的行,并且添加appId和appSecret。

第二步,如果在创建账户后需要做一些其他的操作,修改AccountController.cs中的ExternalLoginConfirmation方法。

4. Identity身份

4.1 使用Claim添加自定义的字段

Identity 是第一个产生出来为每个用户识别身份的。AccountRegister方法先生成创建一个IdentityResult,然后再使用SignInAsync

Claim是一个关于用户的声明,由Identity provider提供,比如用户1有Admin角色。

Asp.Net生成的数据库中有AspNetUsersAspNetUserRolesAspNetUserClaims表,其中AspNetUserClaims用来存储用户自定义的一些信息。

比如给用户在注册时添加一个名称:

public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
//添加Claims
UserManager.AddClaim(user.Id, new Claim(ClaimTypes.GivenName, model.FirstName));
var service = new CheckingAccountService(HttpContext.GetOwinContext()
.Get<ApplicationDbContext>());
service.CreateCheckingAccount(model.FirstName, model.LastName,
user.Id, 0);
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
} // 如果我们进行到这一步时某个地方出错,则重新显示表单
return View(model);
}

获取Claims

var identity = (ClaimsIdentity) User.Identity;
var name = identity.FindFirstValue(ClaimTypes.GivenName) ?? identity.GetUserName();

4.2 在model中添加自定义的字段

打开IdentityModels.cs,在ApplicationUser中添加:

public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public string Pin { get; set; }
}

5 基于角色的认证

5.1 为每个用户添加余额显示

每个Controller都有一个User属性,获取当前UserId的方法如下:

var userId = User.Identity.GetUserId();

比如,我们要获取之前定义的账户余额,可以打开CheckingAccountController.cs中添加下面的代码

private ApplicationDbContext db = new ApplicationDbContext();

//
// GET: /CheckingAccount/Details/
public ActionResult Details()
{
var userId = User.Identity.GetUserId();
var checkingAccount = db.CheckoutAccounts.First(c => c.ApplicationUserId == userId);
return View(checkingAccount);
}

这样每个用户就都能看到自己的账户余额了。

5.2 显示用户账户余额列表

CheckingAccountController.cs中添加:

public ActionResult List()
{
return View(db.CheckoutAccounts.ToList());
}

现在,我们为List添加视图,右键:

注意,如果按照上图配置发生错误,并且错误是“运行所选代码生成器时出错”,那么应该将数据上下文类留空,这样就可以了。

然后编辑生成的模板,将编辑改为:

@Html.ActionLink("详细", "DetailsForAdmin", new { id=item.Id }) |

并且,在CheckingAccountController.cs中添加:

[Authorize(Roles = "Admin")]
public ActionResult DetailsForAdmin(int id)
{
var checkingAccount = db.CheckoutAccounts.First(c => c.Id == id);
return View("Details", checkingAccount);
}

请注意,我们添加了[Authorize(Roles="Admin")]来限定只有Admin组的才能访问,下一节我们讲介绍如何使用角色分配。

6 给用户赋值角色

打开Migrations\Configurations,在Seed方法中添加如下:

protected override void Seed(AspNetMVCEssential.Models.ApplicationDbContext context)
{
//UserStore一定要使用context作为参数
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore); if (!context.Users.Any(u => u.UserName == "liulixiang1988"))
{
//1、创建用户
var user = new ApplicationUser { UserName = "liulixiang1988", Email = "liulixiang1988@gmail.com" };
//下面这句会创建一个用户并且会立即执行,不需调用SaveChanges
userManager.Create(user, "passW0rd"); //2、创建用户相关的账户
var service = new CheckingAccountService(context);
service.CreateCheckingAccount("liulixiang1988", "管理员", user.Id, 1000); //3、添加角色并保存
context.Roles.AddOrUpdate(r => r.Name, new IdentityRole { Name = "Admin" });
context.SaveChanges(); //4、给用户添加角色,指定Id和角色名
userManager.AddToRole(user.Id, "Admin"); }
}

ASP.NET MVC5 学习笔记-4 OWIN和Katana的更多相关文章

  1. ASP.NET MVC5学习笔记01

    由于之前在项目中也使用MVC进行开发,但是具体是那个版本就不是很清楚了,但是我觉得大体的思想是相同的,只是版本高的在版本低的基础上增加了一些更加方便操作的东西.下面是我学习ASP.NET MVC5高级 ...

  2. ASP.NET MVC5学习笔记之Filter提供体系

    前面我们介绍了Filter的基本使用,但各种Filter要在合适的时机运行起来,需要预先准备好,现在看看ASP.NET MVC框架是怎么做的. 一.Filter集合 在ControlerActionI ...

  3. ASP.NET MVC5学习笔记之Controller同步执行架构分析

    在开始之前,声明一下,由于ASP.NET MVC5正式发布了,后面的分析将基于ASP.NET MVC5最新的源代码.在前面的内容我们分析了怎样根据路由信息来确定Controller的类型,并最终生成C ...

  4. ASP.NET MVC5 学习笔记-1 控制器、路由、返回类型、选择器、过滤器

    [TOC] 1. Action 1.1 新建项目 新建项目->Web->Asp.net Web应用程序,选择MVC,选择添加测试. 在解决方案上右键,选择"管理NuGet程序包& ...

  5. ASP.NET MVC5学习笔记之Filter基本介绍

    Filter是ASP.NET MVC框架提供的基于AOP(面向方面)设计,提供在Action执行前后做一些非业务逻辑通用处理,如用户验证,缓存等.现在来看看Filter相关的一些类型信息. 一.基本类 ...

  6. ASP.NET MVC5 学习笔记-2 Razor

    1. Razor @*注释*@ 你在用 @Request.Browser.Browser, 发送邮件给support@qq.com, 转义@@qq @{ var amounts = new List& ...

  7. ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供

    一. 元数据描述类型ModelMetadata 模型元数据是对Model的描述信息,在ASP.NET MVC框架中有非常重要的作用,在模型绑定,模型验证,模型呈现等许多地方都有它的身影.描述Model ...

  8. ASP.NET MVC5学习笔记之Action参数模型绑定基本过程

    当我们在Controller中定义一个Action,通常会定义一个或多个参数,每个参数称为一个模型,ASP.NET MVC框架提供了一种机制称为模型绑定,会尝试自动从请求的信息中实例化每一个模型并赋值 ...

  9. ASP.NET MVC5 学习笔记-3 Model

    1. Model 1.1 添加一个模型 注意,添加属性时可以输入"prop",会自动输入代码段. public class CheckoutAccount { public int ...

随机推荐

  1. frameset常用属性

    框架是网页画面分成几个框窗(不同的窗口对应不同页面以几个网页的形式显示),同时取得多个 src的地址.页面所有框架标记需要放在一个总起的 html 档,这个档案只记录了该框架如何分割 ,不会显示任何资 ...

  2. web - 清除浮动

    最理想的方式为 伪类 + content : 例如 div:after{content:"";display:block;clear:both;} div{zoom:1;} 另外, ...

  3. iOS手机号正则表达式并实现344格式 (正则的另一种实现方式)

    [Demo下载地址]https://git.oschina.net/remainedmute/PhoneNumDemo.git 相关博客http://www.jianshu.com/p/00da4d8 ...

  4. button变成href (即按钮超链效果)

    法一:   这种方法适合做单纯的HTML静态页面,因为它只有button的显示效果,但不能真的跳转.貌似是鸡肋,没多大用. 法二: 1.新打开一个页面 2.本页打开 在超链中实现打开新页面用targe ...

  5. virtualBox文件共享

    具体过程,可以参考: http://jingyan.baidu.com/article/2fb0ba40541a5900f2ec5f07.html 共享命令:sudo mount -t vboxsf ...

  6. 保存属性至xml并读取

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

  7. php知识--递归

    <?php // /* * 遍历输出文件夹中的所有内容 * @param1 string $dir,要遍历的路径 * @param2 int $level = 0,当前的级别 */ functi ...

  8. codeforces 455C 并查集

    传送门 给n个点, 初始有m条边, q个操作. 每个操作有两种, 1是询问点x所在的连通块内的最长路径, 就是树的直径. 2是将x, y所在的两个连通块连接起来,并且要合并之后的树的直径最小,如果属于 ...

  9. get the execution time of a sql statement.

    declare @d datetimeset @d = GETDATE()select * from dbo.spt_valuesselect [语句执行花费时间(毫秒)]= DATEDIFF(ms, ...

  10. C#对象赋值出现的诡异问题,或许你也遇到过,有待你的解决

    前言:今天在代码中,又出现了这个问题,就是对象赋值给一个新的对象时,然后更改新对象中的属性,就会把老对象的值也更改,以前也遇到这个问题,只是没有深究,今天刚好又遇到了此问题,我决定写下来,和大家一起分 ...