如何使用 ASP.NET 5 MVC 6 保护 Web API
Posted
技术标签:
【中文标题】如何使用 ASP.NET 5 MVC 6 保护 Web API【英文标题】:How to protect a Web API using ASP.NET 5 MVC 6 【发布时间】:2015-06-22 20:54:37 【问题描述】:我有一个不错的 ASP.NET 5 / MVC 6 应用程序正在运行。基本上出于这个目的,它只是您在开始一个新项目时获得的普通示例应用程序,以使其保持简单。到目前为止,我可以:
注册用户 登录 退出 保护页面(强制登录等)现在,我想要为应用程序提供一种 API 机制来登录并获取身份验证令牌。具体来说,我正在开发两个要测试的移动应用程序,一个使用 Angular / Cordova,一个使用 Xamarin。
我从高处到低处,似乎都找不到一个例子来说明如何使这项工作发挥作用。到目前为止,我发现的每个示例都假设用户将通过正常的 Web 表单/发布周期登录,然后被带到加载 Angular 的页面,并且身份验证令牌已经在浏览器中。
MVC 控制器的 AccountController.cs 文件中的相关代码如下。我最终想要的是等效功能,但来自一个纯 API 调用,允许 Angular/Xamarin 向它发送用户名/密码并取回身份验证令牌或失败。
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
ViewBag.ReturnUrl = returnUrl;
if (ModelState.IsValid)
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
if (result.Succeeded)
return RedirectToLocal(returnUrl);
if (result.RequiresTwoFactor)
return RedirectToAction("SendCode", new ReturnUrl = returnUrl, RememberMe = model.RememberMe );
if (result.IsLockedOut)
return View("Lockout");
else
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
// If we got this far, something failed, redisplay form
return View(model);
使用 ASP.NET MVC 6 保护 Web API 的推荐方法是什么?
【问题讨论】:
这可以帮助你:***.com/a/25928738/1295965 这可以帮助你bitoftech.net/2014/06/01/… 它不是 vnext,但我能够将这种方法迁移到 vnext。 您必须使用“个人账户”实现 API。这很简单。您使用用户名/密码进行注册,并且 Web API 为您提供了一个令牌,您可以使用它来访问 API。 我有一个正在开发的应用程序,但我无法向公众分享该代码,因为它仍在进行中并且是商业项目。许多开发人员都需要这个特定的集合代码,所以我会在这个周末专门写一篇关于这个的完整博客文章,所以将赏金再延长 1 周。 @alekkowalczyk 您是如何设法创建令牌的? ASP.NET 5 没有内置 OAuth 授权服务器。 【参考方案1】:我认为保护 WebApi2 的推荐方法是通过授权服务器。授权服务器负责生成令牌。但基于this,作为Katana3 一部分的基于OAuth2 的授权服务器已从Asp.Net 5 中删除。
我假设您的应用还不是实时应用,因为 ASP.NET 5 和 MVC 6 都还没有处于最终发布阶段。因此,如果您可以更改您的身份/身份验证过程,您可以使用 Thinktecture 的IdentityServer3。
Dominick Baier 已在博客中介绍了 The State of Security on ASP.NET 5 and MVC 6 以及 IdSvr3 的作用。该博客有一个指向示例 API 控制器的 Github 存储库的链接,还有一个 API 客户端。它还具有 MVC Web 应用程序的示例。 And it can work with Asp.Net Identity.
更新:
如果这对您不起作用,您可以尝试AspNet.Security.OpenIdConnect.Server。请注意,它在 Github 上有未解决的问题,因此您可能会在使用它时遇到问题。还要注意它的依赖关系,尤其是 azureadwebstacknightly。
请注意,ASP.NET 5 和 MVC 6 可能处于稳定的 beta 版本中,但它们仍处于 beta 版本中。它仍然可以改变。
此外,IdSvr3 v2.0 可能处于其最终版本,但它是由一个单独的团队开发的。而且它仅在 2 周前发布,因此恕我直言,就像大多数软件一样,您可能会遇到可能错过测试的事情。请注意 ASP.NET Team,上周,tweeted 关于 IdSvr3 (v2.0) 的发布,所以看起来他们正在认可它。
【讨论】:
有趣。我正在研究他们的解决方案。 IdentityServer3 的不幸之处在于它们不支持 Core CLR。 还没有,但他们计划这样做。 Dominick 在我引用/链接到的 Asp.net OAuth2 问题日志上发布的回复中对此发表了评论。 仅供参考,示例不起作用。我必须进行多项更改才能启动它。 @Martin,如果您在相关的 Github 存储库问题跟踪中记录您遇到的问题,它可能会帮助其他使用示例的人,如果它不存在的话。 我已经记录了几个问题(例如两个 Startup.Configure 方法,无法解析包等)。他们提供的样本不起作用。【参考方案2】:这是我承诺的博客文章,这是初稿,对有 ASP.NET MVC 5 经验的人会有所帮助:Bookstore - Web API with Authorization
Github 上的完整源代码:https://github.com/kbajpai/bookstore
授权 API:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using Bookstore.Models;
namespace Bookstore.Controllers
public class BooksController : ApiController
private BooksDbContext db = new BooksDbContext();
// GET: api/Books
[Authorize(Roles="superuser,user")]
public IQueryable<Book> GetBooks()
return db.Books;
// GET: api/Books/5
[ResponseType(typeof(Book))]
[Authorize(Roles = "superuser,user")]
public async Task<IHttpActionResult> GetBook(string id)
Book book = await db.Books.FindAsync(id);
if (book == null)
return NotFound();
return Ok(book);
// PUT: api/Books/5
[ResponseType(typeof(void))]
[Authorize(Roles = "superuser")]
public async Task<IHttpActionResult> PutBook(string id, Book book)
if (!ModelState.IsValid)
return BadRequest(ModelState);
if (id != book.Id)
return BadRequest();
db.Entry(book).State = EntityState.Modified;
try
await db.SaveChangesAsync();
catch (DbUpdateConcurrencyException)
if (!BookExists(id))
return NotFound();
else
throw;
return StatusCode(HttpStatusCode.NoContent);
// POST: api/Books
[Authorize(Roles = "superuser")]
[ResponseType(typeof(Book))]
public async Task<IHttpActionResult> PostBook(Book book)
if (!ModelState.IsValid)
return BadRequest(ModelState);
db.Books.Add(book);
try
await db.SaveChangesAsync();
catch (DbUpdateException)
if (BookExists(book.Id))
return Conflict();
else
throw;
return CreatedAtRoute("DefaultApi", new id = book.Id , book);
// DELETE: api/Books/5
[Authorize(Roles = "superuser")]
[ResponseType(typeof(Book))]
public async Task<IHttpActionResult> DeleteBook(string id)
Book book = await db.Books.FindAsync(id);
if (book == null)
return NotFound();
db.Books.Remove(book);
await db.SaveChangesAsync();
return Ok(book);
protected override void Dispose(bool disposing)
if (disposing)
db.Dispose();
base.Dispose(disposing);
private bool BookExists(string id)
return db.Books.Count(e => e.Id == id) > 0;
【讨论】:
问题是针对 ASP.NET 5 MVC 6,而不是 ASP.NET MVC 5。 MVC6 与 MVC5 有很大不同吗?这个想法是一样的。 是的Kunal,MVC6与MVC5有很大不同 @KunalB。真是太不可思议了。随着框架到组件的全新分解以及跨平台的重建......这确实是 MVC 的重生,迁移场景在许多方面都变得微不足道。以上是关于如何使用 ASP.NET 5 MVC 6 保护 Web API的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Asp.Net 5 (MVC 6) 中使用实体框架 6.x
如何在 ASP.NET 5 MVC 6 (vNext) 中定义 Identity 的密码规则?
如何在 ASP.NET MVC 5、Entity Framework 6 中使用流利的 API 映射表?