C# 是否可以对ASP.NET Identity 2.0中创建的表使用ASP.NET成员身份进行身份验证?
我有一个基于MVC4的web门户,它只使用成员身份验证用户(不创建新用户,不验证密码) 以下是用于验证用户身份的表的屏幕截图: 以下是用户尝试进行身份验证时触发的操作方法:C# 是否可以对ASP.NET Identity 2.0中创建的表使用ASP.NET成员身份进行身份验证?,c#,asp.net,.net,asp.net-mvc,asp.net-identity,C#,Asp.net,.net,Asp.net Mvc,Asp.net Identity,我有一个基于MVC4的web门户,它只使用成员身份验证用户(不创建新用户,不验证密码) 以下是用于验证用户身份的表的屏幕截图: 以下是用户尝试进行身份验证时触发的操作方法: [HttpPost] public ActionResult Login(string username, string password, string[] rememberMe, string returnUrl) { if(Membership.ValidateUser(use
[HttpPost]
public ActionResult Login(string username, string password, string[] rememberMe, string returnUrl)
{
if(Membership.ValidateUser(username, password))
{
if (rememberMe != null)
{
FormsAuthentication.SetAuthCookie(username, true);
}
Response.Redirect(returnUrl);
}
ViewBag.ErrorMessage = "wrong credentials";
return View();
}
以下是web配置:
<membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider"
connectionStringName="SiteSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="8"
minRequiredPasswordLength="4"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d43e4e" />
</providers>
</membership>
我的任务是对新表进行用户身份验证
(即,我需要用于身份验证的成员资格,即asp.net identity 2.0创建的表)
因此,出于这个目的,我认为我需要定制成员资格以读取新表
我的问题是,是否可以对成员身份进行更改,以读取asp.net identity 2.0进行身份验证?是的,这是可能的,但解决方案将取决于您当前的具体实现。有三种解决方案立即浮现在脑海中:
用对新系统的调用替换所有身份验证逻辑
从长远来看,这是更易于管理的,因为您只需要在一个地方维护auth逻辑
- 如果您有一个可以通过HTTP访问的已部署API,那么这是最简单的解决方案,但它可以通过包含DLL来工作,只要它们是根据兼容的.Net版本编译的
- 如果你有其他应用程序(桌面/网络/移动)也使用了新的API,那么这个老网站就会成为新网站的客户端
这是最低的代码解决方案,也是唯一一个我们不必关心正确散列密码以进行比较的解决方案
如果另一个系统是在线API,那么您可以使用HttpClient简单地调用另一个站点进行身份验证,如何进行身份验证将取决于API支持哪种类型的身份验证协议
using System.Web.Security;
[HttpPost]
public async Task<ActionResult> Login(string username, string password, string[] rememberMe, string returnUrl)
{
if(await ValidateUser(username, password))
{
if (rememberMe != null)
{
FormsAuthentication.SetAuthCookie(username, true);
}
Response.Redirect(returnUrl);
}
ViewBag.ErrorMessage = "wrong credentials";
return View();
}
public async Task<bool> Login(string username, string password)
{
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("grant_type", "password");
data.Add("username", username);
data.Add("password", password);
// Example, replace this with your own.
string apiAuthUrl = "http://localhost:3000/token";
var response = await client.PostAsync(apiAuthUrl, new System.Net.Http.FormUrlEncodedContent(data));
return response.IsSuccessStatusCode;
}
然后实现成员资格提供程序类:
using System.Web.Security;
public class CustomMembershipProvider : MembershipProvider
{
public override MembershipUser CreateUser(string username, string password,
string email, string passwordQuestion, string passwordAnswer,
bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
/// we're not creating new users in this site!
throw new NotImplementedException();
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
var user = /* Your User Repo Lookup */;
if (user != null)
{
MembershipUser memUser = new MembershipUser("CustomMembershipProvider",
username, user.UserID, user.UserEmailAddress,
string.Empty, string.Empty,
true, false, DateTime.MinValue,
DateTime.MinValue,
DateTime.MinValue,
DateTime.Now, DateTime.Now);
return memUser;
}
return null;
}
public override bool ValidateUser(string username, string password)
{
// This is highly dependent on how passwords are encrypted in the new system
// Assuming it is a simple MD5 Hash, we just need to create the same Hash
string sha1Pswd = GetMD5Hash(password);
// TODO: Now use this hash to verify that the username and password match a user in your repo
var user = /*Lookup a user that matches the username and password.*/;
if (user != null)
return true;
return false;
}
public override int MinRequiredPasswordLength
{
get { return 4; }
}
/// <summary> Simple MD5 Hash algorithm, you will need to match this against the process used in the other system </summary>
public static string GetMD5Hash(string value)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(value));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
}
您可能还需要实现部分或全部视图,但这在很大程度上取决于MVC站点实际使用的成员API中的方法
你试过什么?通常我们只是编写一个包装器来替换成员资格提供者,这没什么大不了的,但是您尝试过吗?您在MVC端使用概要文件还是角色?如果你这样做了,就短路not@ChrisSchaller,我不使用角色,你能澄清什么是配置文件吗?这是一个很好的回答,意味着你没有使用它:)配置文件很酷,别误会,我喜欢这个概念,但多年来只在两个应用程序中使用过它。使用新模式的另一个系统是在线API吗?您可以通过http调用它,只需替换成员身份。ValidateUser()
?这将是最短的路径,如果你没有使用任何其他呼叫的会员APIChris,谢谢你的帖子。我正在尝试使用2种解决方案。但是,在登录finction中,我在此行Membership.ValidateUser(用户名、密码)和FormsAuthentication.SetAuthCookie上收到错误。错误文本为:当前上下文中不存在名称“FormsAuthentication”,当前上下文中不存在名称“Membership”。知道我为什么会出错吗?您需要为标准System.Web.Security
命名空间包含引用和using语句。我忽略了这一点,因为你说你正在扩展一个已经有身份验证的系统,我会更新帖子。是的,系统有身份验证,我创建了一个新项目,添加了所有需要的引用,并根据codeproject中的文章进行了所有重载,在web.config文件中进行了更改,并在新项目中创建了app.config文件。对新项目的引用已添加到主项目中。当我在这一行:Membership.ValidUser上导航并单击defentition时,我希望我会被导航到重载类,但它会将我带到原始dll。因此,我用system.web.security对其进行了注释。如果成员资格提供程序注册正确,则在运行时调用membership.ValidateUser()
将在内部调用您的CustomMembershipProvider.ValidateUser()
。我们称之为提供者模式,有时称之为插件模式。它调用System.Web.Security
名称空间是正确的,其要点是在Web.config中做一个简单的更改,而不更改任何代码,瞧,您的站点正在使用另一个提供程序/architexture来实现安全性。因此,不必启动新项目,此解决方案的要点是,它是非破坏性的,并且易于在现有项目中实施。只有web.config
中的更改才会触发auth调用以使用CustomMembershipProvider
。