我继承了一个遗留框架dll,它有自己的方法来登录和查看用户所属的“组”。这是一个非常典型的本土安全模块。你通过传统的dll方法与它交谈。它不使用或与任何现代.Net认证/授权框架交谈。
我创建了一个MVC5应用程序并获得了很多样板文件,包括AccountController
,我完全认为最好全部使用它,因为那是“用谷物编码”而不是“反对谷物”。
我想对MVC项目样板代码进行 minimal 更改,让它从遗留dll中获取答案。一旦有了这些认证/授权答案,我希望它继续进行,好像它从.Net框架获得了那些答案。
仅使用登录方案作为示例,
以下是AccountController
中的给定样板方法:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
//SignInStatus result = Login(model.Email, model.Password);
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
这是我的例行程序,从我的遗产dll获得“类似于足够映射”的答案:
private SignInStatus Login(string userId, string password)
{
string SoftwareLicenses = "blahblahblah";
try
{
UserCredentials = UserProfileType.Login(userId, password, 0, SoftwareLicenses);
return SignInStatus.Success;
}
catch (AtlasBusinessRuleException abrex)
{
switch (abrex.Message)
{
case "Invalid Login Name entered":
return SignInStatus.Failure;
case "Invalid Password entered":
return SignInStatus.Failure;
case "Your password has expired. Please change the password.":
return SignInStatus.LockedOut;
default:
return SignInStatus.Failure;
}
}
}
请参阅,如果我只是在样板例程中取消注释我对例程的调用,这还不足以打开我登录的所有.Net框架意识以及我是谁等等。我完全理解角色是不同的但是现在我已经满足于只是登录并让网站表现得就像我用它的代码那样。
更新
这可能与它在ApplicationUserManager
的{{1}}文件中创建的ApplicationSignInManager
和IdentityConfig
有关。
答案 0 :(得分:0)
我使用了一种新方法来得出答案。我得出答案的方式比答案本身更重要。
Microsoft.AspNet.Identity.Core
和Microsoft.AspNet.Identity.Owin
UserManager
和SignInManager
SignInManager.PasswordSignInAsync()
AccountController.Login(LoginViewModel model, string returnUrl)
ApplicationSignInManager
。将virtual
关键字更改为override
。ApplicationSignInManager.cs (覆盖2种方法,注释掉会破坏的代码)
using System.Threading.Tasks;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using AACOMvc.Models;
using System.Data.Entity.Utilities;
using Microsoft.AspNet.Identity;
using System;
namespace AAAMvc
{
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
if (UserManager == null)
{
return SignInStatus.Failure;
}
var user = await UserManager.FindByNameAsync(userName).WithCurrentCulture();
if (user == null)
{
return SignInStatus.Failure;
}
//if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
//{
// return SignInStatus.LockedOut;
//}
if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture())
{
//await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture();
return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
}
//if (shouldLockout)
//{
// // If lockout is requested, increment access failed count which might lock out the user
// await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
// if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
// {
// return SignInStatus.LockedOut;
// }
//}
return SignInStatus.Failure;
}
private async Task<SignInStatus> SignInOrTwoFactor(ApplicationUser user, bool isPersistent)
{
var id = Convert.ToString(user.Id);
//if (await UserManager.GetTwoFactorEnabledAsync(user.Id).WithCurrentCulture()
// && (await UserManager.GetValidTwoFactorProvidersAsync(user.Id).WithCurrentCulture()).Count > 0
// && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id).WithCurrentCulture())
//{
// var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie);
// identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id));
// AuthenticationManager.SignIn(identity);
// return SignInStatus.RequiresVerification;
//}
await SignInAsync(user, isPersistent, false).WithCurrentCulture();
return SignInStatus.Success;
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
}
ApplicationUserManager.cs (覆盖了4种方法,注释掉的代码,并添加了我的代码,使其按照传统dll的方式工作)
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using AACOMvc.Models;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using HerculesBusinessModel;
using System.Security.Claims;
using System.Data.Entity.Utilities;
namespace AAAMvc
{
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static UserCredentialsType UserCredentials
{
get
{
return (UserCredentialsType)System.Web.HttpContext.Current.Session["UserProfile"];
}
set
{
System.Web.HttpContext.Current.Session["UserProfile"] = value;
}
}
public override async Task<bool> CheckPasswordAsync(ApplicationUser user, string password)
{
if (user == null)
{
return false;
}
await Task.Delay(0);
string SoftwareLicenses = "blahblahblah";
try
{
UserCredentials = UserProfileType.Login(user.UserName, password, 0, SoftwareLicenses);
return true;
}
catch (HerculesBusinessRuleException ex)
{
}
return false;
}
public override async Task<ClaimsIdentity> CreateIdentityAsync(ApplicationUser user, string authenticationType)
{
//ThrowIfDisposed();
if (user == null)
{
throw new ArgumentNullException("user");
}
const string IdentityProviderClaimType =
"http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider";
const string DefaultIdentityProviderClaimValue = "ASP.NET Identity";
var id = new ClaimsIdentity(authenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id, ClaimValueTypes.String));
id.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, user.UserName, ClaimValueTypes.String));
id.AddClaim(new Claim(IdentityProviderClaimType, DefaultIdentityProviderClaimValue, ClaimValueTypes.String));
if (SupportsUserRole)
{
IList<string> roles = await GetRolesAsync(user.Id).WithCurrentCulture();
foreach (string roleName in roles)
{
id.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, roleName, ClaimValueTypes.String));
}
}
if (SupportsUserClaim)
{
//id.AddClaims(await GetClaimsAsync(user.Id).WithCurrentCulture());
}
return id;
}
ApplicationUser user;
public override async Task<ApplicationUser> FindByNameAsync(string userName)
{
await Task.Delay(0);
var profile = UserProfileType.FetchUserProfileForLogin(userName);
if (profile != null)
{
user = new ApplicationUser()
{
UserName = profile.LoginName,
Id = profile.Id.ToString()
};
foreach (decimal groupId in profile.UserGroups)
{
user.Roles.Add(new IdentityUserRole() { UserId = profile.Id.ToString(), RoleId = groupId.ToString() });
}
}
return user;
}
public override async Task<IList<string>> GetRolesAsync(string userId)
{
////ThrowIfDisposed();
//var userRoleStore = GetUserRoleStore();
//var user = await FindByIdAsync(userId).WithCurrentCulture();
//if (user == null)
//{
// throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound,
// userId));
//}
//return await userRoleStore.GetRolesAsync(user).WithCurrentCulture();
await Task.Delay(0);
return user.Roles.Select(r => r.RoleId).ToList();
}
}
}
我很惊讶并且非常高兴一个有点机器人的过程可以得出答案。但是我更加高兴的是,使用这个过程教会了我更多关于一个奇怪的新命名空间(Microsoft.AspNet.Identity
)的知识,而不是我在几个小时的阅读或谷歌搜索中学到的。它可能不完美,但我可以使用相同的过程来改善我在这里所拥有的。