Mic*_*ael 5 .net c# asp.net asp.net-mvc asp.net-identity
我有一个基于 MVC4 的 Web 门户,仅使用成员资格来验证用户身份(不创建新用户,不验证密码)。
以下是用于验证用户身份的表的屏幕截图:
以下是用户尝试进行身份验证时触发的操作方法:
[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();
}
Run Code Online (Sandbox Code Playgroud)
这是网络配置:
<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>
Run Code Online (Sandbox Code Playgroud)
我还有一个由 ASP.NET Identity 2.0 创建的新数据库:
我的任务是针对新表进行用户身份验证(即我需要用于身份验证的成员资格,由 asp.net Identity 2.0 创建的表)。
因此,为此目的,我认为我需要自定义成员资格以读取新表。
我的问题是否可以对成员身份进行更改,使其读取 asp.net Identity 2.0 进行身份验证?
是的,这是可能的,但这是解决方案取决于您当前的具体实现的问题之一。我立即想到了三种解决方案:
将所有身份验证逻辑替换为对新系统的调用
从长远来看,这更易于管理,因为您只需在一处维护身份验证逻辑。
这是最低代码的解决方案,也是唯一一个我们不必关心正确散列密码以进行比较的解决方案。
如果对方系统是在线 API,那么您可以使用 HttpClient 简单地调用其他站点进行身份验证,具体操作方式取决于 API 支持什么类型的身份验证协议
使用 System.Web.Security;
[http邮报]
公共异步任务 <ActionResult> 登录(字符串用户名,字符串密码,字符串[] RememberMe,字符串returnUrl)
{
if(等待ValidateUser(用户名,密码))
{
如果(记住我!= null)
{
FormsAuthentication.SetAuthCookie(用户名, true);
}
Response.Redirect(returnUrl);
}
ViewBag.ErrorMessage = "凭据错误";
返回视图();
}
公共异步任务<bool>登录(字符串用户名,字符串密码)
{
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<字符串, 字符串> data = new Dictionary<字符串, 字符串>();
data.Add("grant_type", "密码");
data.Add("用户名", 用户名);
数据.Add("密码", 密码);
// 例如,将其替换为您自己的。
字符串 apiAuthUrl = "http://localhost:3000/token";
var response = wait client.PostAsync(apiAuthUrl, new System.Net.Http.FormUrlEncodedContent(data));
返回响应.IsSuccessStatusCode;
}
如果其他系统没有作为 API 发布,即桌面样式应用程序,那么您可以通过直接引用和调用 dll 中的 Auth 方法来执行类似的操作。
创建自定义成员资格提供程序
这是一个基于代码的解决方案,与 2.0 中的工作方式类似,但涉及的内容更多一些。
Scott Gu 发布的源代码曾经是此类活动的有用参考:内置 ASP.NET 2.0 提供程序的源代码现已可供下载
但链接似乎已损坏!
MS Docs 仍然有一些阅读内容,但没有来源:Implementing a Membership Provider
以下文章来自第一个原理方法,您的表已经创建,因此只需关注访问数据,而不是创建新表
不必实现提供程序的所有方面,只需实现站点代码将调用的那些方法即可。
这个解决方案很好,因为您不必更改任何现有代码,只需添加新代码并更改 web.config
更改 web.config 引用以使用您的自定义提供程序,替换MyNamespace.Providers为您的实际命名空间!:
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;
}
然后实现会员提供者类:
使用 System.Web.Security;
公共类 CustomMembershipProvider :MembershipProvider
{
公共覆盖MembershipUser CreateUser(字符串用户名,字符串密码,
字符串电子邮件、字符串密码问题、字符串密码答案、
bool isApproved,对象providerUserKey,out MembershipCreateStatus状态)
{
/// 我们不会在此站点中创建新用户!
抛出新的NotImplementedException();
}
公共覆盖 MembershipUser GetUser(字符串用户名, bool userIsOnline)
{
var user = /* 您的用户存储库查找 */;
if (用户!= null)
{
MembershipUser memUser = new MembershipUser("CustomMembershipProvider",
用户名、用户.用户ID、用户.用户电子邮件地址、
字符串.空,字符串.空,
true、false、DateTime.MinValue、
日期时间.MinValue,
日期时间.MinValue,
日期时间.Now, 日期时间.Now);
返回内存用户;
}
返回空值;
}
公共覆盖 bool ValidateUser(字符串用户名,字符串密码)
{
// 这很大程度上取决于新系统中密码的加密方式
// 假设是一个简单的MD5 Hash,我们只需要创建相同的Hash
字符串 sha1Pswd = GetMD5Hash(密码);
// TODO:现在使用此哈希来验证用户名和密码是否与存储库中的用户匹配
var user = /*查找与用户名和密码匹配的用户*/;
if (用户!= null)
返回真;
返回假;
}
公共覆盖 int MinRequiredPasswordLength
{
得到{返回4; }
}
/// <summary> 简单的 MD5 哈希算法,您需要将其与其他系统中使用的过程进行匹配 </summary>
公共静态字符串GetMD5Hash(字符串值)
{
MD5 md5Hasher = MD5.Create();
byte[] 数据 = md5Hasher.ComputeHash(Encoding.Default.GetBytes(value));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
返回 sBuilder.ToString();
}
}
自定义 AspNetSqlMembershipProvider 使用的存储过程
取决于您的优势,这可能更简单,并且是一个选项,因为 MVC 站点已经配置了此提供程序,我们需要做的就是修改提供程序用于执行身份验证的 SQL 存储过程要求。
以下是有关如何实现提供程序的好读物
在 MVC5 中使用 AspNetSqlMembershipProvider
配置 Web 应用程序以利用 ASP.NET 应用程序服务数据库
您可以设置一个空白数据库并使用 aspnet_regsql 配置它来查看存储过程(它们不会位于您的新数据库中!)。
<membership defaultProvider="CustomMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="CustomMembershipProvider"
type="MyNamespace.Providers.CustomMembershipProvider"
connectionStringName="SiteSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
maxInvalidPasswordAttempts="8"
minRequiredPasswordLength="4"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
applicationName="DotNetNuke" />
</providers>
</membership>
Run Code Online (Sandbox Code Playgroud)
您可能还需要实现部分或全部视图,但这在很大程度上取决于您的 MVC 站点实际使用的 Membership API 中的方法。