如何使用 Web API 来对 MVC 应用程序进行身份验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用 Web API 来对 MVC 应用程序进行身份验证相关的知识,希望对你有一定的参考价值。

参考技术A 首先,让我们先更新 API 项目

我们将先对 API 项目进行必要的修改,修改完成之后再切换到 Web 项目对客户端进行更新。

第1步:我们需要一个数据库

在能做任何操作之前我们需要先创建一个数据库。本例中将使用 SQL Server Express。如果你没有安装,可以从这里下载 SQL Server Express。安装完成之后,创建一个名为 CallingWebApiFromMvc 的数据库。这就是第一步要做的。

Api 项目还需要一个数据库连接字符串,否则我们寸步难行。把下面这段代码插入到 Api 项目的Web.config 文件中:

<connectionStrings>
<add name="ApiFromMvcConnection" connectionString="Data Source=(local);Initial Catalog=CallingWebApiFromMvc;Integrated Security=True" providerName="System.Data.SqlClient" /></connectionStrings>

认证(Identity)框架会自动创建我们管理用户所需要的成员关系表,现在不需要担心去提前创建它们。

第2步:添加相关的Nuget包

接下来我们添加用于OWIN和Windows认证的Nuget包。打开包管理控制台,切换Api项目为缺省项目,输入以下命令:

Install-Package Microsoft.AspNet.WebApi.Owin
Install-Package Microsoft.Owin.Host.SystemWeb
Install-Package Microsoft.AspNet.Identity.EntityFramework
Install-Package Microsoft.AspNet.Identity.Owin

使用这些包可以在我们的应用中启动一个OWIN服务器,然后通过EntityFramework把我们的用户保存到SQL Server。

第3步:添加管理用户的Identity类

我们使用基于Windows认证机制之上的Entity框架来管理数据库相关的业务。首先我们需要添加一些用于处理的类。在Api项目里添加一个Identity目录作为我们要添加类的命名空间。然后添加如下的类:

public class ApplicationUser : IdentityUser



public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
public ApplicationDbContext() : base("ApiFromMvcConnection")
public static ApplicationDbContext Create()
return new ApplicationDbContext();



注意我们传给基类构造函数的参数ApiFromMvcConnection要和Web.config中的连接字符串中的name相匹配。

public class ApplicationUserManager : UserManager<ApplicationUser>
public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store)

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
var manager = new ApplicationUserManager(new UserStore<ApplicationUser> (context.Get<ApplicationDbContext> ()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser> (manager)

AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
;
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator

RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
; var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)

manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser> (dataProtectionProvider.Create("ASP.NET Identity"));
return manager;



第4步:添加OWIN启动类

为了让我们的应用程序作为OWIN服务器上运行,我们需要在应用程序启动时初始化。我们可以通过一个启动类做到这一点。我们将装点这个类的
OwinStartup属性,因此在应用程序启动时触发。这也意味着,我们可以摆脱的Global.asax和移动它们的
Application_Start代码转换成我们新的启动类。

using Microsoft.Owin;

[assembly: OwinStartup(typeof(Levelnis.Learning.CallingWebApiFromMvc.Api.Startup))]
namespace Levelnis.Learning.CallingWebApiFromMvc.Api

using System;
using System.Web.Http;
using Identity;
using Microsoft.Owin.Security.OAuth;
using Owin;
using Providers;
public class Startup
public void Configuration(IAppBuilder app)

GlobalConfiguration.Configure(WebApiConfig.Register);
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager> (ApplicationUserManager.Create); var oAuthOptions = new OAuthAuthorizationServerOptions

TokenEndpointPath = new PathString("/api/token"),
Provider = new ApplicationOAuthProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
AllowInsecureHttp = true
;
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(oAuthOptions);




在应用程序启动时,我们正在建立自己的服务器。在这里,我们配置令牌端点并设置自己的自定义提供商,我们用我们的用户进行身份验证。在我们的例子中,我们使用了ApplicationOAuthProvider类。让我们来看看现在:

第5步:添加OAuth的提供商

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

context.Validated();
return Task.FromResult<object> (null);

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

var userManager = context.OwinContext.GetUserManager<ApplicationUserManager> ();
var user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)

context.SetError("invalid_grant", "The user name or password is incorrect."); return;

var oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); var cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); var properties = CreateProperties(user.UserName); var ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);

private static AuthenticationProperties CreateProperties(string userName)

var data = new Dictionary<string, string>


"userName", userName

;
return new AuthenticationProperties(data);



我们感兴趣的是这里2种方法。第一,ValidateClientAuthentication,只是验证客户端。我们有一个客户端,所以返回成
功。这是一个异步方法签名但没有异步调用发生。正因为如此,我们可以离开了异步修改,但我们必须返回一个任务自己。我们增加了一个名为
GenerateUserIdentityAsync的ApplicationUser,它看起来像这样的方法:

public class ApplicationUser : IdentityUser
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)

var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
return userIdentity;



第6步:注册一个新用户 - API端
所以,我们有到位的所有Identity类管理用户。让我们来看看RegisterController,将新用户保存到我们的数据库。它接受一个RegisterApi模式,这是简单的:

public class RegisterApiModel

[Required]
[EmailAddress] public string Email get; set;

[Required]
[StringLength(100, ErrorMessage = "The 0 must be at least 2 characters long.", MinimumLength = 6)]
public string Password
get; set;


[Required]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword get; set;


控制器本身,如果注册成功只是返回一个200 OK响应。如果验证失败,则返回401错误请求的响应。

public class RegisterController : ApiController
private ApplicationUserManager UserManager
get
return Request.GetOwinContext().GetUserManager<ApplicationUserManager> ();

public IHttpActionResult Post(RegisterApiModel model)
if (!ModelState.IsValid)
return BadRequest(ModelState);
var user = new ApplicationUser

Email = model.Email,
UserName = model.Email,
EmailConfirmed = true
;
var result = UserManager.Create(user, model.Password);
return result.Succeeded ? Ok() : GetErrorResult(result);

private IHttpActionResult GetErrorResult(IdentityResult result)

if (result == null)

return InternalServerError();

if (result.Errors != null)

foreach (var error in result.Errors)

ModelState.AddModelError("", error);


if (ModelState.IsValid)

// No ModelState errors are available to send, so just return an empty BadRequest.
return BadRequest();

return BadRequest(ModelState);

如何使用基于 cookie 的身份验证授权 Web API

【中文标题】如何使用基于 cookie 的身份验证授权 Web API【英文标题】:How authorize a web API using a cookie based authentication 【发布时间】:2021-08-09 09:41:36 【问题描述】:

我有一个 MCV 核心应用程序,它使用基于 cookie 的身份验证(将用户凭据存储在数据库中)。后来我介绍了一个 web api 作为这个 MVC 应用程序的后端。现在两者都作为 Azure Web 应用程序托管在一起。目前我的 cookie 身份验证逻辑仍在 MVC 应用程序中。那么对我来说保护 web api 的最简单方法是什么。

【问题讨论】:

你如何验证你的用户?天蓝色广告? 不只是使用传统方法。将用户名和密码存储在数据库中。 both are hosted in Azure as a single web 是什么意思?相同的应用服务计划? 是的,在同一个资源计划中,但我的意思是这两个应用程序都作为一个 Web 应用程序运行。前端和后端一起托管在同一个应用中。 所以你有一个 SPA 和一个后端? 【参考方案1】:

我只是在我的 API 控制器中使用了 Authorize 属性并解决了这个问题。

【讨论】:

以上是关于如何使用 Web API 来对 MVC 应用程序进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Web API 来对 MVC 应用程序进行身份验证

如何使用 Web API 来对 MVC 应用程序进行身份验证

如何使用 ASP.NET 5 MVC 6 保护 Web API

如何在 Asp.net MVC 中添加 Web Api,然后在同一个应用程序中使用 WebAPI

如何将自定义标头从 mvc 项目发送到 Web api 项目?

如何将 Web API 添加到现有的 ASP.NET MVC (5) Web 应用程序项目中?