我需要为现有的 MySQL 数据库创建 Web API C# 应用程序。我已经设法使用 Entity Framework 6 将每个数据库表绑定(bind)到 RESTful API (允许 CRUD 操作)。
我想实现一个登录/注册系统(以便我可以在未来实现角色和权限,并限制某些 API 请求)。
我必须使用的 MySQL 数据库有一个用户表 (称为 user
),它具有以下不言自明的列:
id
电子邮件
用户名
password_hash
似乎身份验证的事实标准是 ASP.Net Identity。我花了最后一个小时试图弄清楚如何使 Identity 与现有的 DB-First Entity Framework 设置一起工作。
如果我尝试构造 ApplicationUser
实例来存储 user
实例(来自 MySQL 数据库的实体) 来检索用户数据,我得到以下结果错误:
The entity type ApplicationUser is not part of the model for the current context.
我假设我需要将身份数据存储在我的 MySQL 数据库中,但找不到任何关于如何做到这一点的资源。我已经尝试完全删除 ApplicationUser
类并使我的 user
实体类派生自 IdentityUser
,但调用 UserManager.CreateAsync
导致 LINQ to Entities 转换错误。
如何在具有现有 user
实体的 Web API 2 应用程序中设置身份验证?
最佳答案
你说:
I want to implement a login/registration system (so that I can implement roles and permissions in the future, and restrict certain API requests).
How do I setup authentication in a Web API 2 application, having an existing user entity?
这绝对意味着您不需要需要 ASP.NET Identity。 ASP.NET Identity 是一种处理所有用户信息的技术。它实际上并没有“制定”身份验证机制。 ASP.NET Identity 使用 OWIN 身份验证机制,这是另一回事。
您要查找的不是“如何将 ASP.NET Identity 与我现有的用户表一起使用”,而是“如何使用我现有的用户表配置 OWIN 身份验证”强>
要使用 OWIN Auth,请按照以下步骤操作:
安装包:
Owin
Microsoft.AspNet.Cors
Microsoft.AspNet.WebApi.Client
Microsoft.AspNet.WebApi.Core
Microsoft.AspNet.WebApi.Owin
Microsoft.AspNet.WebApi.WebHost
Microsoft.Owin
Microsoft.Owin.Cors
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security
Microsoft.Owin.Security.OAuth
创建 Startup.cs
根文件夹中的文件(示例):
确保 [assembly: OwinStartup] 已正确配置
[assembly: OwinStartup(typeof(YourProject.Startup))]
namespace YourProject
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
//other configurations
ConfigureOAuth(app);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/api/security/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(2),
Provider = new AuthorizationServerProvider()
};
app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
try
{
//retrieve your user from database. ex:
var user = await userService.Authenticate(context.UserName, context.Password);
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
//roles example
var rolesTechnicalNamesUser = new List<string>();
if (user.Roles != null)
{
rolesTechnicalNamesUser = user.Roles.Select(x => x.TechnicalName).ToList();
foreach (var role in user.Roles)
identity.AddClaim(new Claim(ClaimTypes.Role, role.TechnicalName));
}
var principal = new GenericPrincipal(identity, rolesTechnicalNamesUser.ToArray());
Thread.CurrentPrincipal = principal;
context.Validated(identity);
}
catch (Exception ex)
{
context.SetError("invalid_grant", "message");
}
}
}
}
使用 [Authorize]
属性来授权操作。
调用api/security/token
与 GrantType
, UserName
, 和 Password
获取不记名 token 。像这样:
"grant_type=password&username=" + username + "&password=" password;
在 HttpHeader Authorization
内发送 token 作为Bearer "YOURTOKENHERE"
.像这样:
headers: { 'Authorization': 'Bearer ' + token }
希望对您有所帮助!
关于c# - DB-First 身份验证与 ASP.NET Web API 2 + EF6 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33398961/