既然是个小平台,那么肯定有用户认证模块,微软提供了一个认证框架供我们使用Microsoft.Owin,首先我们通过Nuget安装相关的资源包!
web需要安装如下:
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Core.zh-Hans" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin.zh-Hans" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net452" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />
Application项目安装如下:
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Core.zh-Hans" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin.zh-Hans" version="2.2.1" targetFramework="net452" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />
Nuget资源包安装完成后我们开始写代码了。
首先我们在Application项目的Customers文件中建立Dto,新增实体Customer并且继承Domain的Customer,以及实现IUser《int》(因为我的实体对象主键是int型)。
[AutoMap(typeof(Blog_Solution.Domain.Customers.Customer))]
public class Customer : Blog_Solution.Domain.Customers.Customer, IUser<int>
{
public Customer()
{
this.PasswordSalt = CommonHelper.GenerateRandomDigitCode(6);
}
public string UserName
{
get
{
return this.LoginName;
}
set
{
this.UserName = LoginName;
}
}
}
Customers文件中增加CustomerStore 类并且实现接口IUserStore《Customer,int》(注:Customer为dto的实体)。我们只需要实现我们所用到的部分函数就可以了
/// <summary>
/// 用户仓储
/// </summary>
public class CustomerStore : IUserStore<Customer,int>
{
#region Fields && Ctor
private readonly ICustomerService _customerService;
public CustomerStore(ICustomerService customerService)
{
this._customerService = customerService;
}
#endregion
#region Method
public Task CreateAsync(Customer user)
{
throw new NotImplementedException();
}
public Task DeleteAsync(Customer user)
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
public async Task<Customer> FindByIdAsync(int userId)
{
var customer = _customerService.GetCustomerById(userId);
return new Customer
{
Id = customer.Id,
CreationTime = customer.CreationTime,
CustomerRoleId = customer.CustomerRoleId,
Deleted = customer.Deleted,
Email = customer.Email,
LastIpAddress = customer.LastIpAddress,
LastModificationTime = customer.LastModificationTime,
LoginName = customer.LoginName,
Mobile = customer.Mobile,
Password = customer.Password,
PasswordSalt = customer.PasswordSalt,
PasswordFormat = customer.PasswordFormat,
PasswordFormatId = customer.PasswordFormatId,
};
}
public async Task<Customer> FindByNameAsync(string userName)
{
var customer = _customerService.GetCustomerByLoginName(userName);
return new Customer
{
Id = customer.Id,
CreationTime = customer.CreationTime,
CustomerRoleId = customer.CustomerRoleId,
Deleted = customer.Deleted,
Email = customer.Email,
LastIpAddress = customer.LastIpAddress,
LastModificationTime = customer.LastModificationTime,
LoginName = customer.LoginName,
Mobile = customer.Mobile,
Password = customer.Password,
PasswordSalt = customer.PasswordSalt,
PasswordFormat = customer.PasswordFormat,
PasswordFormatId = customer.PasswordFormatId,
};
}
public Task UpdateAsync(Customer user)
{
throw new NotImplementedException();
}
#endregion
}
声明用户管理器CustomerManager实现类UserManager《Customer, int》(customer为dto的实体)
public class CustomerManager : UserManager<Customer, int>
{
public CustomerManager(IUserStore<Customer, int> store) : base(store)
{
}
}
声明用户登录管理器LoginManager
/// <summary>
/// 登录模块
/// </summary>
public class LoginManager : SignInManager<Customer, int>, IApplicationService
{
private readonly UserManager<Customer, int> _userManager;
private readonly IAuthenticationManager _authenticationManager;
public LoginManager(UserManager<Customer, int> userManager, AuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
this._userManager = userManager;
this._authenticationManager = authenticationManager;
}
public override Task SignInAsync(Customer user, bool isPersistent, bool rememberBrowser)
{
return base.SignInAsync(user, isPersistent, rememberBrowser);
}
}
我们最后在Application项目中找到Blog_SolutionApplicationModule类,重写函数如下:
public override void PostInitialize()
{
IocManager.Register<IAuthenticationManager, AuthenticationManager>();
IocManager.Register<IUserStore<Customer, int>, CustomerStore>();
IocManager.Register<UserManager<Customer, int>, CustomerManager>();
//IocManager.Register<SignInManager<Customer, int>, LoginManager>();
//base.PostInitialize();
}
上面这段代码是为了注入项目中。
好了,基础工作我们搞定了,现在只需要配置好控制就可以了
public class AccountController : Blog_SolutionControllerBase
{
#region Fields && Ctor
private readonly LoginManager _loginManage;
private readonly CustomerManager _customerManager;
private readonly IAuthenticationService _authenticationService;
public AccountController(IAuthenticationService authenticationService,
LoginManager loginManager,
CustomerManager customerManager)
{
this._authenticationService = authenticationService;
this._loginManage = loginManager;
this._customerManager = customerManager;
}
#endregion
#region Utilities
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
#endregion
#region Login / Logout
public ActionResult Login(string returnUrl = "")
{
if (string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = Request.ApplicationPath;
}
ViewBag.returnUrl = returnUrl;
var model = new LoginModel();
return View(model);
}
[HttpPost]
[DisableAuditing]
public ActionResult Login(LoginModel model)
{
var loginResult = _authenticationService.ValidateCustomer(model.LoginName, model.Password);
switch (loginResult.Result)
{
case LoginResults.Successful:
{
//生成ClaimsIdentity
var identity = _loginManage.CreateUserIdentity(loginResult.Customer);
//用户登录
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = model.RememberMe }, identity);
if (String.IsNullOrEmpty(model.ReturnUrl) || !Url.IsLocalUrl(model.ReturnUrl))
return RedirectToAction("Index", "Home");
return Redirect(model.ReturnUrl);
}
case LoginResults.Deleted:
ModelState.AddModelError("", L("Account.Login.WrongCredentials.Deleted"));
break;
case LoginResults.NotActive:
ModelState.AddModelError("", L("Account.Login.WrongCredentials.NotActive"));
break;
case LoginResults.NotRegistered:
ModelState.AddModelError("", L("Account.Login.WrongCredentials.NotRegistered"));
break;
case LoginResults.WrongPassword:
default:
ModelState.AddModelError("", L("Account.Login.WrongCredentials"));
break;
}
return View(model);
}
public ActionResult Logout()
{
AuthenticationManager.SignOut();
return Redirect("/");
}
#endregion
}
所有步骤完成后,我们还有最后一步,就是在你的web项目中增加一个启动项(Owin Start类)
[assembly: OwinStartup(typeof(Blog_Solution.Web.App_Start.Startup))]
namespace Blog_Solution.Web.App_Start
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
CookieHttpOnly = true,
CookieName = "__BLOG_WEB"
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
private static bool IsTrue(string appSettingName)
{
return string.Equals(
ConfigurationManager.AppSettings[appSettingName],
"true",
StringComparison.InvariantCultureIgnoreCase);
}
}
}
搞定了!
这样,我们就完成用户的认证模块,在abp项目中,只要在生命周期内,可以使用AbpSession.UserId来获取用户的主键信息。
博客开源地址 https://github.com/5ina/BlogSolution
开发地址 https://github.com/5ina/BlogSolution.git
欢迎进群讨论 68848430
扫一扫,MrColor每天都有新内容