我们通过使用用户凭据调用webservice并返回包含用户ID的WCF结构(“LogonTicket”)来覆盖MVC3应用程序中的基本身份验证。此LogonTicket用于“对每次对Web服务进行的调用对用户进行身份验证。
现在,我们通过替换Web.config中的defaultProvider来覆盖。我们在这个被覆盖的提供者所做的就是 覆盖ValidateUser()函数。这就是我们用他们的凭据和返回来调用Web服务的地方 “LogonTicket”。
这是我们AccountController的LogOn()函数,基本上是模板的基本代码:
public ActionResult LogOn(LogOnModel model)
{
string ReturnUrl = "";
if (HttpContext.Request.UrlReferrer.Query.Length > 11)
{
ReturnUrl = Uri.UnescapeDataString(HttpContext.Request.UrlReferrer.Query.Substring(11));
}
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl) && ReturnUrl.Length > 1 && ReturnUrl.StartsWith("/")
&& !ReturnUrl.StartsWith("//") && !ReturnUrl.StartsWith("/\\"))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
ViewBag.MainWebsite = MainWebsite;
return View(model);
}
这是来自新默认提供程序的重写的ValidateUser()函数:
public override bool ValidateUser(string username, string password)
{
MyServiceClient mps = new MyServiceClient();
string sha1password = HashCode(password);
LogonInfo logonInfo = mps.GetLogonTicket(username, sha1password);
if (logonInfo.LogonTicket != "" && logonInfo.LogonTicket != "0")
{
// Authenticated so set session variables
HttpContext.Current.Session["LogonTicket"] = logonInfo.LogonTicket;
HttpContext.Current.Session["ParticipantID"] = logonInfo.ParticipantID;
return true;
}
else
{
return false;
}
}
我不确定如何结合使用这两者,所以我的问题是:
感谢您查看我的问题。
答案 0 :(得分:3)
我做了一个需要多种登录可能性的项目(自定义帐户,Google和Facebook)
最后,使用ASP.NET进行身份验证完全取决于您的配置。 (在您的情况下,它是FormsAuthentication)这意味着FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
基本上确定了与您的用户有关的所有内容以及您设置的位置不受限制。
您现在基本上与我们开始时的实现相同,使用MembershipProvider来处理您自己的自定义帐户。您现在只需要扩展以方便openIds。您必须针对每种登录类型展开Controller
各种操作(现在您可以添加ActionResult LogOn()
,例如:ActionResult LogOnOpenId()
)。在该方法中,您基本上调用相同的代码,而不是Membership.ValidateUser(model.UserName, model.Password)
,而是调用OpenId服务。
我在下面提供了使用dotnetopenauth进行谷歌实施的示例。服务方法使用formsService.SignIn(userId.Value.ToString(), false);
,它基本上调用FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
(我们只针对SecurityPrincipal执行一些自定义行为,但这不会影响您的身份验证过程)。您还可以看到我们在收到新用户时创建了一个新帐户。为了解决您的问题第2部分,我们已经实现了一个可以合并的配置文件,如果您可以提供另一个登录。这允许我们的用户保持他们的帐户合并并使用他们喜欢的任何登录方法。
关于多个登录的示例,我将参考Tomas的答案,他们将StackExchange作为一个很好的例子。另外我建议你安装MVC4和VS2012,然后做一个文件>新项目。最新的MVC默认模板包括openid实现和自定义登录!
示例google openid实施:
控制器方法:
public virtual ActionResult LoginGoogle(string returnUrl, string runAction)
{
using (var openId = new OpenIdRelyingParty())
{
IAuthenticationResponse response = openId.GetResponse();
// If we have no response, start
if (response == null)
{
// Create a request and redirect the user
IAuthenticationRequest req = openId.CreateRequest(WellKnownProviders.Google);
var fetch = new FetchRequest();
fetch.Attributes.AddRequired(WellKnownAttributes.Name.First);
fetch.Attributes.AddRequired(WellKnownAttributes.Name.Last);
fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
fetch.Attributes.AddRequired(WellKnownAttributes.Preferences.Language);
req.AddExtension(fetch);
req.RedirectToProvider();
return null;
}
_service.ConnectViaGoogle(response, TempData);
}
服务方法:
public void ConnectViaGoogle(IAuthenticationResponse response, TempDataDictionary tempData)
{
// We got a response - check it's valid and that it's me
if (response.Status == AuthenticationStatus.Authenticated)
{
var claim = response.GetExtension<FetchResponse>();
Identifier googleUserId = response.ClaimedIdentifier;
string email = string.Empty;
string firstName = string.Empty;
string lastName = string.Empty;
string language = string.Empty;
if (claim != null)
{
email = claim.GetAttributeValue(WellKnownAttributes.Contact.Email);
firstName = claim.GetAttributeValue(WellKnownAttributes.Name.First);
lastName = claim.GetAttributeValue(WellKnownAttributes.Name.Last);
language = claim.GetAttributeValue(WellKnownAttributes.Preferences.Language);
}
//Search User with google UserId
int? userId = _userBL.GetUserIdByGoogleSingleSignOnId(googleUserId);
//if not exists -> Create
if (!userId.HasValue)
{
_userBL.CreateGoogleUser(
googleUserId,
firstName,
lastName,
email,
language,
DBConstants.UserStatus.DefaultStatusId,
out userId);
}
if (userId.HasValue)
{
_userBL.UpdateLastLogon(userId.Value);
var formsService = new FormsAuthenticationService();
formsService.SignIn(userId.Value.ToString(), false);
AfterLoginActions(tempData);
}
}
}
有任何问题或意见吗?我很乐意听到他们的声音。
答案 1 :(得分:1)
我希望这会有所帮助,但如果您有任何疑问,请详细说明您的问题。