NET使用ABP框架搭建博客项目(二) 认证模块

时间:2023-01-16 22:26:53

既然是个小平台,那么肯定有用户认证模块,微软提供了一个认证框架供我们使用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

NET使用ABP框架搭建博客项目(二) 认证模块

扫一扫,MrColor每天都有新内容