using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using HMS_Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http.Features;
using HMS_Service.Services.MasterService;
using HMS_Service.Services.PatientVisitService;
using HMS_Service.UserManagementService;
using HMS_Service.Services.PatientRegistrationService;
using HMS_Service.Services.BloodCampService;
using HMS_Service.Services.AccountService;
using System;
using Microsoft.AspNetCore.Identity;
using HMS_Presentation.Services;
using HMS_Service.Services.InventoryManagementService;
using HMS_Service.Services.SystemManagementService;
using HMS_Service.Services.UserManagementService;
using HMS_Service.Services.LabManagementService;
using HMS_Service.CacheSetting.AppSettings;
using HMS_Service.Services.BarCodeService;
namespace HMS_Presentation
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IAppSettings, AppSettings>();
services.AddMemoryCache();
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDbContext<_DbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<HMS_POCO.UserManagement.ApplicationUser, HMS_POCO.UserManagement.ApplicationRole>(
option => {
option.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
option.Lockout.MaxFailedAccessAttempts = 5;
option.Lockout.AllowedForNewUsers = false;
})
.AddEntityFrameworkStores<HMS_Context._DbContext>()
.AddDefaultTokenProviders();
/*Cache Functionality Start*/
/*Cache Functionality End*/
services.AddAuthorization(options =>
{
options.AddPolicy("Administrator", policy => policy.RequireRole("Admin","Superior"));
options.AddPolicy("Doctors", policy => policy.RequireRole("Receptionist","Doctor", "Superior"));
options.AddPolicy("Nurses", policy => policy.RequireRole("Nurse", "Superior"));
options.AddPolicy("Labortory", policy => policy.RequireRole("LabTech", "Superior"));
options.AddPolicy("Accountants", policy => policy.RequireRole("Accountant", "Superior"));
options.AddPolicy("Receptionist", policy => policy.RequireRole("Receptionist", "Superior"));
options.AddPolicy("RecpDoct", policy => policy.RequireRole("Receptionist","Doctor", "Superior"));
options.AddPolicy("RMO", policy => policy.RequireRole("RMO", "Superior"));
options.AddPolicy("RD", policy => policy.RequireRole("RMO", "Doctor","Superior"));
// Access DNL(Doctor,Nurse ,Lab)
options.AddPolicy("AccessDNL", policy => policy.RequireRole("Doctor", "Nurse", "LabTech", "Superior"));
});
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "YourAppCookieName";
options.LoginPath = "/UserAccount/Login";
options.LogoutPath = "/UserAccount/Logout";
options.AccessDeniedPath = "/UserAccount/AccessDenied";
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
});
services.AddDistributedMemoryCache();
services.AddSession(options=>options.Cookie.HttpOnly=true);
services.AddMvc().AddSessionStateTempDataProvider();
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<FormOptions>(x => {
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = long.MaxValue;
x.BufferBodyLengthLimit = long.MaxValue;
x.MemoryBufferThreshold = int.MaxValue;
x.ValueCountLimit = int.MaxValue;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseSession();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
**User Account Controller**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using HMS_Presentation.Services;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authentication;
using HMS_Presentation.Models.AccountViewModels;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Security.Claims;
using HMS_Service.UserManagementService;
using Microsoft.AspNetCore.Http;
using HMS_Service.Services.UserManagementService;
using HMS_POCO.UserManagement;
namespace HMS_Presentation.Controllers
{
[Authorize(Policy = "Administrator")]
[Route("[controller]/[action]")]
public class UserAccountController : Controller
{
private readonly UserManager<HMS_POCO.UserManagement.ApplicationUser> _userManager;
private readonly SignInManager<HMS_POCO.UserManagement.ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly RoleManager<HMS_POCO.UserManagement.ApplicationRole> _roleManager;
//Extra Addition
private readonly EmployeeService _employeeService;
private readonly UserAccessLogService _userAccessLogService;
public UserAccountController(
UserManager<HMS_POCO.UserManagement.ApplicationUser> userManager,
SignInManager<HMS_POCO.UserManagement.ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<UserAccountController> logger,
RoleManager<HMS_POCO.UserManagement.ApplicationRole> roleManager,
EmployeeService employeeService, UserAccessLogService userAccessLogService)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_roleManager = roleManager;
_employeeService = employeeService;
_userAccessLogService = userAccessLogService;
}
[TempData]
public string ErrorMessage { get; set; }
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
USER_ACCESS_LOG be = new USER_ACCESS_LOG();
be.AccessTime = DateTime.Now.ToString();
be.UserName = model.Email;
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
var lookupUser = _userManager.Users.Where(c => c.UserName == model.Email).FirstOrDefault();
HttpContext.Session.SetInt32("UserId", lookupUser.EmpId);
_logger.LogInformation("User logged in.");
be.AccessedStatus = true;
_userAccessLogService.Add(be);
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
var lookupUser = _userManager.Users.Where(c => c.UserName == model.Email).FirstOrDefault();
HttpContext.Session.SetInt32("UserId", lookupUser.EmpId);
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
be.AccessedStatus = false;
_userAccessLogService.Add(be);
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> LoginWith2fa(bool rememberMe, string returnUrl = null)
{
// Ensure the user has gone through the username & password screen first
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
throw new ApplicationException($"Unable to load two-factor authentication user.");
}
var model = new LoginWith2faViewModel { RememberMe = rememberMe };
ViewData["ReturnUrl"] = returnUrl;
return View(model);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty);
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine);
if (result.Succeeded)
{
_logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id);
return RedirectToLocal(returnUrl);
}
else if (result.IsLockedOut)
{
_logger.LogWarning("User with ID {UserId} account locked out.", user.Id);
return RedirectToAction(nameof(Lockout));
}
else
{
_logger.LogWarning("Invalid authenticator code entered for user with ID {UserId}.", user.Id);
ModelState.AddModelError(string.Empty, "Invalid authenticator code.");
return View();
}
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> LoginWithRecoveryCode(string returnUrl = null)
{
// Ensure the user has gone through the username & password screen first
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
throw new ApplicationException($"Unable to load two-factor authentication user.");
}
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginWithRecoveryCode(LoginWithRecoveryCodeViewModel model, string returnUrl = null)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
throw new ApplicationException($"Unable to load two-factor authentication user.");
}
var recoveryCode = model.RecoveryCode.Replace(" ", string.Empty);
var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);
if (result.Succeeded)
{
_logger.LogInformation("User with ID {UserId} logged in with a recovery code.", user.Id);
return RedirectToLocal(returnUrl);
}
if (result.IsLockedOut)
{
_logger.LogWarning("User with ID {UserId} account locked out.", user.Id);
return RedirectToAction(nameof(Lockout));
}
else
{
_logger.LogWarning("Invalid recovery code entered for user with ID {UserId}", user.Id);
ModelState.AddModelError(string.Empty, "Invalid recovery code entered.");
return View();
}
}
[HttpGet]
[AllowAnonymous]
public IActionResult Lockout()
{
return View();
}
[HttpGet]
public IActionResult Register(string returnUrl = null)
{
ViewData["RoleName"] = new SelectList(_roleManager.Roles, "Id", "Name");
ViewData["EmployeeName"] = new SelectList(_employeeService.GetUnRegisteredEmployee(), "Id", "FirstName");
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new HMS_POCO.UserManagement.ApplicationUser { UserName = model.Email, Email = model.Email, EmpId=model.EmployeeId};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
IdentityRole res = await _roleManager.FindByIdAsync(model.RoleId);
await _userManager.AddToRoleAsync(user, res.Name);
_logger.LogInformation("User created a new account with password.");
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
ViewData["RoleName"] = new SelectList(_roleManager.Roles, "Id", "Name");
ViewData["EmployeeName"] = new SelectList(_employeeService.GetAll(), "Id", "FirstName");
return View(model);
}
[AllowAnonymous]
public async Task<IActionResult> Logout()
{
HttpContext.Session.Clear();
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
return RedirectToAction(nameof(HomeController.Index), "Home");
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToAction(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
return RedirectToLocal(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToAction(nameof(Lockout));
}
else
{
// If the user does not have an account, then ask the user to create an account.
ViewData["ReturnUrl"] = returnUrl;
ViewData["LoginProvider"] = info.LoginProvider;
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
}
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
throw new ApplicationException("Error loading external login information during confirmation.");
}
var user = new HMS_POCO.UserManagement.ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewData["ReturnUrl"] = returnUrl;
return View(nameof(ExternalLogin), model);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{userId}'.");
}
var result = await _userManager.ConfirmEmailAsync(user, code);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
[HttpGet]
[AllowAnonymous]
public IActionResult ForgotPassword()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
{
// Don't reveal that the user does not exist or is not confirmed
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
// For more information on how to enable account confirmation and password reset please
// visit https://go.microsoft.com/fwlink/?LinkID=532713
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailAsync(model.Email, "Reset Password",
$"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
// If we got this far, something failed, redisplay form
return View(model);
}
[HttpGet]
[AllowAnonymous]
public IActionResult ForgotPasswordConfirmation()
{
return View();
}
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPassword(string code = null)
{
if (code == null)
{
throw new ApplicationException("A code must be supplied for password reset.");
}
var model = new ResetPasswordViewModel { Code = code };
return View(model);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction(nameof(ResetPasswordConfirmation));
}
var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction(nameof(ResetPasswordConfirmation));
}
AddErrors(result);
return View();
}
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPasswordConfirmation()
{
return View();
}
[HttpGet]
public IActionResult AccessDenied()
{
return View();
}
#region Helpers
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
#endregion
}
}
这是我的Startup.cs文件的代码。和用户帐户控制器authorize标记不能正确保持会话状态..即使经过会话时间之后,应用程序仍可启动,无需电子邮件和密码。如何解决。我正在使用.NET CORE和Visual Studio 2017,当我注销然后运行该应用程序时,它可以正常工作并接受电子邮件和密码。但没有注销该帐户并关闭选项卡,然后运行该应用程序时出现问题...
答案 0 :(得分:0)
在下面提到的默认登录方法中使用IsPersistent=true
:
var result = await _signInManager.PasswordSignInAsync(user, model.LoginPassword, true, false);
第三个参数是IsPersistent,对于永久登录应该为true。