Added HttpException class for missing HttpException for net8 Wrapped HttpContext.Session, GetJsonResult, IsAjaxRequest and GetUserIdentityName in controllers for net8 Added AuthenticationService to test Fab2ApprovalMKLink code for net8 Compile conditionally flags to debug in dotnet core
401 lines
12 KiB
C#
401 lines
12 KiB
C#
#if !NET8
|
|
using System.Web;
|
|
using System.Web.Mvc;
|
|
using System.Web.Security;
|
|
#endif
|
|
|
|
#if NET8
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
#endif
|
|
|
|
#if !NET8
|
|
using Fab2ApprovalSystem.DMO;
|
|
using Fab2ApprovalSystem.Misc;
|
|
using Fab2ApprovalSystem.Models;
|
|
#endif
|
|
|
|
#if !NET8
|
|
using Microsoft.AspNet.Identity;
|
|
using Microsoft.AspNet.Identity.EntityFramework;
|
|
using Microsoft.AspNet.Identity.Owin;
|
|
using Microsoft.Owin.Security;
|
|
#endif
|
|
|
|
#if !NET8
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json;
|
|
#endif
|
|
|
|
namespace Fab2ApprovalSystem.Controllers;
|
|
|
|
[Authorize]
|
|
#if NET8
|
|
[Route("[controller]")]
|
|
#endif
|
|
public class AccountController : Controller {
|
|
|
|
#if !NET8
|
|
|
|
public AccountController()
|
|
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) {
|
|
}
|
|
|
|
public AccountController(UserManager<ApplicationUser> userManager) {
|
|
UserManager = userManager;
|
|
}
|
|
|
|
public UserManager<ApplicationUser> UserManager { get; private set; }
|
|
|
|
#endif
|
|
|
|
#if !NET8
|
|
// GET: /Account/Login
|
|
[AllowAnonymous]
|
|
// try to make the browser refresh the login page every time, to prevent issues with changing usernames and the anti-forgery token validation
|
|
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
|
|
#endif
|
|
public ActionResult Login(string returnUrl) {
|
|
ViewBag.ReturnUrl = returnUrl;
|
|
return View();
|
|
}
|
|
|
|
#if !NET8
|
|
|
|
private void SetSessionParameters(LoginResult loginResult, LoginModel user) {
|
|
GlobalVars.SetSessionParameters(GetSession(), loginResult, user);
|
|
|
|
FormsAuthentication.SetAuthCookie(user.LoginID, true);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AllowAnonymous]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<ActionResult> Login(LoginModel model, string returnUrl) {
|
|
try {
|
|
bool isLoginValid;
|
|
|
|
HttpClient httpClient = HttpClientFactory.Create();
|
|
httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
|
|
|
|
LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model);
|
|
|
|
#if (DEBUG)
|
|
isLoginValid = true;
|
|
|
|
#endif
|
|
#if (!DEBUG)
|
|
|
|
bool isIFX = false;
|
|
if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
|
|
isLoginValid = true;
|
|
} else {
|
|
isLoginValid = loginResult.IsAuthenticated;
|
|
if (isLoginValid)
|
|
isIFX = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (isLoginValid) {
|
|
UserAccountDMO userDMO = new UserAccountDMO();
|
|
LoginModel user = userDMO.GetUser(model.LoginID);
|
|
if (user != null) {
|
|
SetSessionParameters(loginResult, user);
|
|
|
|
return RedirectToLocal(returnUrl);
|
|
} else {
|
|
ModelState.AddModelError("", "The user name does not exist in the DB. Please contact the System Admin");
|
|
}
|
|
} else {
|
|
ModelState.AddModelError("", "The user name or password provided is incorrect.");
|
|
}
|
|
} catch (Exception ex) {
|
|
Functions.WriteEvent(GlobalVars.AppSettings, GetUserIdentityName() + " " + ex.InnerException, System.Diagnostics.EventLogEntryType.Error);
|
|
EventLogDMO.Add(new WinEventLog() { IssueID = 99999, UserID = GetUserIdentityName(), DocumentType = "Login", OperationType = "Error", Comments = "Reject - " + ex.Message });
|
|
ModelState.AddModelError("", ex.Message);
|
|
}
|
|
|
|
return View(model);
|
|
// If we got this far, something failed, redisplay form
|
|
}
|
|
|
|
[HttpPost]
|
|
[AllowAnonymous]
|
|
public async Task<HttpResponseMessage> ExternalAuthSetup(AuthAttempt authAttempt) {
|
|
try {
|
|
bool isLoginValid;
|
|
|
|
HttpClient httpClient = HttpClientFactory.Create();
|
|
httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
|
|
|
|
LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt);
|
|
|
|
#if (DEBUG)
|
|
isLoginValid = true;
|
|
|
|
#endif
|
|
#if (!DEBUG)
|
|
|
|
bool isIFX = false;
|
|
if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
|
|
isLoginValid = true;
|
|
} else {
|
|
isLoginValid = loginResult.IsAuthenticated;
|
|
if (isLoginValid)
|
|
isIFX = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (isLoginValid) {
|
|
UserAccountDMO userDMO = new UserAccountDMO();
|
|
LoginModel user = userDMO.GetUser(authAttempt.LoginID);
|
|
if (user != null) {
|
|
SetSessionParameters(loginResult, user);
|
|
|
|
return new HttpResponseMessage(HttpStatusCode.OK);
|
|
} else {
|
|
ModelState.AddModelError("", "The user name does not exist in the DB. Please contact the System Admin");
|
|
|
|
return new HttpResponseMessage(HttpStatusCode.NotFound);
|
|
}
|
|
} else {
|
|
ModelState.AddModelError("", "The user name or password provided is incorrect.");
|
|
|
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
|
}
|
|
} catch (Exception ex) {
|
|
Functions.WriteEvent(GlobalVars.AppSettings, GetUserIdentityName() + " " + ex.InnerException, System.Diagnostics.EventLogEntryType.Error);
|
|
EventLogDMO.Add(new WinEventLog() { IssueID = 99999, UserID = GetUserIdentityName(), DocumentType = "Login", OperationType = "Error", Comments = "Reject - " + ex.Message });
|
|
ModelState.AddModelError("", ex.Message);
|
|
|
|
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
// GET: /Account/Register
|
|
[AllowAnonymous]
|
|
public ActionResult Register() {
|
|
return View();
|
|
}
|
|
|
|
#if !NET8
|
|
|
|
// POST: /Account/Disassociate
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<ActionResult> Disassociate(string loginProvider, string providerKey) {
|
|
ManageMessageId? message = null;
|
|
IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
|
|
if (result.Succeeded) {
|
|
message = ManageMessageId.RemoveLoginSuccess;
|
|
} else {
|
|
message = ManageMessageId.Error;
|
|
}
|
|
return RedirectToAction("Manage", new { Message = message });
|
|
}
|
|
|
|
#endif
|
|
|
|
// GET: /Account/Manage
|
|
#pragma warning disable IDE0060 // Remove unused parameter
|
|
public ActionResult Manage(ManageMessageId? message) {
|
|
return View();
|
|
}
|
|
#pragma warning restore IDE0060 // Remove unused parameter
|
|
|
|
#if !NET8
|
|
|
|
// POST: /Account/ExternalLogin
|
|
[HttpPost]
|
|
[AllowAnonymous]
|
|
[ValidateAntiForgeryToken]
|
|
public ActionResult ExternalLogin(string provider, string returnUrl) {
|
|
// Request a redirect to the external login provider
|
|
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
|
|
}
|
|
|
|
// POST: /Account/LinkLogin
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public ActionResult LinkLogin(string provider) {
|
|
// Request a redirect to the external login provider to link a login for the current user
|
|
return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());
|
|
}
|
|
|
|
// GET: /Account/LinkLoginCallback
|
|
public async Task<ActionResult> LinkLoginCallback() {
|
|
ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
|
|
if (loginInfo == null) {
|
|
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
|
|
}
|
|
IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
|
|
if (result.Succeeded) {
|
|
return RedirectToAction("Manage");
|
|
}
|
|
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public ActionResult LogOff() {
|
|
FormsAuthentication.SignOut();
|
|
return RedirectToAction("Login", "Account");
|
|
}
|
|
|
|
#endif
|
|
|
|
[AllowAnonymous]
|
|
public ActionResult ExternalLoginFailure() {
|
|
return View();
|
|
}
|
|
|
|
#if !NET8
|
|
|
|
[ChildActionOnly]
|
|
public ActionResult RemoveAccountList() {
|
|
IList<UserLoginInfo> linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());
|
|
ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;
|
|
return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing) {
|
|
if (disposing && UserManager != null) {
|
|
UserManager.Dispose();
|
|
UserManager = null;
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
#endif
|
|
|
|
#region Helpers
|
|
// Used for XSRF protection when adding external logins
|
|
private const string XsrfKey = "XsrfId";
|
|
|
|
#if !NET8
|
|
|
|
private IAuthenticationManager AuthenticationManager {
|
|
get {
|
|
return HttpContext.GetOwinContext().Authentication;
|
|
}
|
|
}
|
|
|
|
private async Task SignInAsync(ApplicationUser user, bool isPersistent) {
|
|
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
|
|
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
|
|
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
|
|
}
|
|
|
|
private void AddErrors(IdentityResult result) {
|
|
foreach (string error in result.Errors) {
|
|
ModelState.AddModelError("", error);
|
|
}
|
|
}
|
|
|
|
private bool HasPassword() {
|
|
ApplicationUser user = UserManager.FindById(User.Identity.GetUserId());
|
|
if (user != null) {
|
|
return user.PasswordHash != null;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
public enum ManageMessageId {
|
|
ChangePasswordSuccess,
|
|
SetPasswordSuccess,
|
|
RemoveLoginSuccess,
|
|
Error
|
|
}
|
|
|
|
private ActionResult RedirectToLocal(string returnUrl) {
|
|
if (Url.IsLocalUrl(returnUrl)) {
|
|
return Redirect(returnUrl);
|
|
} else {
|
|
return RedirectToAction("MyTasks", "Home");
|
|
}
|
|
}
|
|
|
|
#if !NET8
|
|
|
|
private class ChallengeResult : HttpUnauthorizedResult {
|
|
|
|
#endif
|
|
|
|
#if NET8
|
|
|
|
private class ChallengeResult {
|
|
|
|
#endif
|
|
|
|
public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) {
|
|
}
|
|
|
|
public ChallengeResult(string provider, string redirectUri, string userId) {
|
|
LoginProvider = provider;
|
|
RedirectUri = redirectUri;
|
|
UserId = userId;
|
|
}
|
|
|
|
public string LoginProvider { get; set; }
|
|
public string RedirectUri { get; set; }
|
|
public string UserId { get; set; }
|
|
|
|
#if !NET8
|
|
|
|
public override void ExecuteResult(ControllerContext context) {
|
|
AuthenticationProperties properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
|
|
if (UserId != null) {
|
|
properties.Dictionary[XsrfKey] = UserId;
|
|
}
|
|
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#if !NET8
|
|
|
|
private System.Web.HttpSessionStateBase GetSession() =>
|
|
Session;
|
|
|
|
private JsonResult GetJsonResult(object? data) =>
|
|
Json(data, JsonRequestBehavior.AllowGet);
|
|
|
|
private bool IsAjaxRequest() =>
|
|
Request.IsAjaxRequest();
|
|
|
|
#endif
|
|
|
|
#if NET8
|
|
|
|
private Microsoft.AspNetCore.Http.ISession GetSession() =>
|
|
HttpContext.Session;
|
|
|
|
private JsonResult GetJsonResult(object? data) =>
|
|
Json(data);
|
|
|
|
private bool IsAjaxRequest() =>
|
|
Request.Headers.TryGetValue("X-Requested-With", out Microsoft.Extensions.Primitives.StringValues strings) && strings[0] == "XMLHttpRequest";
|
|
|
|
#endif
|
|
|
|
private string GetUserIdentityName() =>
|
|
@User.Identity.Name;
|
|
|
|
} |