HttpContext.Current.User.Identity.IsAuthenticated 将 okta openidconnect 与 .net 核心项目集成时导致无限重定向循环
HttpContext.Current.User.Identity.IsAuthenticated results in infinite redirect loop when integrating okta openidconnect with .net core project
这里是 startup.cs 我已经按照以下配置了 okta openid connect。请审核
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)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOktaMvc(new OktaMvcOptions
{
// Replace these values with your Okta configuration
OktaDomain = Configuration.GetValue<string>("AppSettings:OktaDomain"),
ClientId = Configuration.GetValue<string>("AppSettings:ClientId"),
ClientSecret = Configuration.GetValue<string>("AppSettings:ClientSecret"),
Scope = new List<string> { "openid", "profile", "email" },
});
//services.AddAuthorization();
services.Configure<FormOptions>(x => x.ValueCountLimit = 8192);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
var lockoutOptions = new LockoutOptions()
{
AllowedForNewUsers = true,
DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5),
MaxFailedAccessAttempts = 3
};
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 0;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Lockout = lockoutOptions;
})
.AddEntityFrameworkStores<AmpCoreContext>().AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.LoginPath = new PathString("/Identity/Account/Login");
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(20); });
services
.AddControllersWithViews()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
// Maintain property names during serialization. See:
// https://github.com/aspnet/Announcements/issues/194
.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddHttpContextAccessor();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var culture = CultureInfo.CreateSpecificCulture("en-US");
var dateformat = new DateTimeFormatInfo
{
ShortDatePattern = "MM/dd/yyyy",
LongDatePattern = "MM/dd/yyyy hh:mm:ss tt"
};
culture.DateTimeFormat = dateformat;
var supportedCultures = new[] { culture };
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(culture),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
try
{
var context = serviceScope.ServiceProvider.GetRequiredService<AmpCoreContext>();
var customers = context.Customer.ToListAsync().Result;
string output =
Newtonsoft.Json.JsonConvert.SerializeObject(customers, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText("tenants.json", output);
}
catch (Exception)
{
throw;
}
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//app.UseCookiePolicy();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
这是我的帐户控制器,在登录按钮上单击我将其重定向到帐户控制器 singin 方法。但它总是在循环中调用。请检查下面的代码
public class AccountController : Controller
{
public IActionResult SignIn()
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
return Challenge(OktaDefaults.MvcAuthenticationScheme);
}
return RedirectToAction("Index", "Home");
}
[HttpPost]
public IActionResult SignOut()
{
return new SignOutResult(
new[]
{
OktaDefaults.MvcAuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme,
},
new AuthenticationProperties { RedirectUri = "/Home/" });
}
}
它重定向到 okta,okta return 但是 HttpContext.User.Identity.IsAuthenticated 在帐户控制器中总是错误的,它是无限循环。
这是家庭控制器
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using Project.Common;
using System;
using Microsoft.AspNetCore.Identity;
using Project.Data.Identity;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.DataProtection;
using Project.Application.Interfaces;
using Project.Application.ViewModel;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Data;
using Microsoft.AspNetCore.Http;
using Project.Data.Data;
using ErrorViewModel = Project.Models.ErrorViewModel;
using System.Linq;
using Okta.AspNetCore;
using Microsoft.AspNetCore.Authorization;
namespace Project.Controllers
{
[Authorize]
public class HomeController : BaseController
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ICustomerService _customerService;
private IPasswordHasher<ApplicationUser> _passwordHasher;
private readonly IFieldService _fieldService;
private IModuleService _moduleService;
private readonly IHttpContextAccessor _httpContextAccessor;
private ISession _session => _httpContextAccessor.HttpContext.Session;
private readonly IUserAccessSecurityService _userAccessSecurityService;
private readonly IGroupService _groupService;
private readonly Context _context;
private IDataProtectionProvider _provider;
private readonly IUserSessionLogService _userSessionLogService;
public HomeController(UserManager<ApplicationUser> userManager, ICustomerService customerService, IPasswordHasher<ApplicationUser> passwordHasher, IFieldService fieldService,
IModuleService moduleService, IUserAccessSecurityService userAccessSecurityService, IGroupService groupService, Context context, IHttpContextAccessor httpContextAccessor,
IDataProtectionProvider provider, SignInManager<ApplicationUser> signInManager, IUserSessionLogService userSessionLogService) : base(signInManager, userAccessSecurityService, provider, userSessionLogService)
{
_userManager = userManager;
_customerService = customerService;
_passwordHasher = passwordHasher;
_fieldService = fieldService;
_moduleService = moduleService;
_userAccessSecurityService = userAccessSecurityService;
_groupService = groupService;
_context = context;
_httpContextAccessor = httpContextAccessor;
_provider = provider;
_userSessionLogService = userSessionLogService;
}
public IActionResult unauthorised()
{
return View("~/Views/Home/AccessDenied.cshtml");
}
[Authorize]
public IActionResult Index()
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") != Guid.Empty)
{
var Fk_Customer = HttpContext.Session.GetObjectFromJson<int>("CurrentCustomer");
var FK_User = HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId");
bool hasGroup = false;
DashBoardViewModel dashBoardViewModel = new DashBoardViewModel();
List<ViewUserGroup> viewUserGroup = new List<ViewUserGroup>();
ApplicationUser appUsers = _context.Users.SingleOrDefault(x => x.Id == FK_User);
bool isSuperAdmin = _context.UserType.Where(x => x.ID == appUsers.FK_UserType && x.Type.ToLower() == "super admin").Any();
bool isAdmin = _context.UserType.Where(x => x.ID == appUsers.FK_UserType && x.Type.ToLower() == "company admin").Any();
viewUserGroup = _userAccessSecurityService.GetUserGroupByUser(Fk_Customer, FK_User);
if (viewUserGroup.Count > 0)
{
if (viewUserGroup[0].Fk_Group != 0 && viewUserGroup[0].PK_Group != 0)
hasGroup = true;
}
ViewBag.hasGroup = hasGroup;
ViewBag.isSuperAdmin = isSuperAdmin;
DataTable dtPendingAssetCount = _fieldService.GetPendingAssetCount(Convert.ToInt32(Fk_Customer), (isAdmin ? true : (isSuperAdmin) ? true : false), FK_User);
if (dtPendingAssetCount != null && dtPendingAssetCount.Rows.Count > 0)
{
dashBoardViewModel.AccountReminder.Pending_Valuation_Count = dtPendingAssetCount.Rows[0]["Pending_Valuation_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Valuation_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_New_Assets_Count = dtPendingAssetCount.Rows[0]["Pending_New_Assets_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_New_Assets_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Change_Request_Count = dtPendingAssetCount.Rows[0]["Pending_Change_Request_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Change_Request_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_New_Assets_State_Count = dtPendingAssetCount.Rows[0]["Pending_New_Assets_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_New_Assets_State_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Change_Request_State_Count = dtPendingAssetCount.Rows[0]["Pending_Change_Request_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Change_Request_State_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Valuation_State_Count = dtPendingAssetCount.Rows[0]["Pending_Valuation_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Valuation_State_Count"]) : 0;
}
dashBoardViewModel.AccountReminder.New_Asset_Pending_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.New_Asset_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.AccountReminder.Pending_Change_Request_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.Change_request_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.AccountReminder.Pending_Valuation_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.Valuation_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.PropertyRisk = _fieldService.GetNumberOfLocationDetails(Fk_Customer);
return View(dashBoardViewModel);
}
else
{
return LocalRedirect("~/Identity/Account/Login");
}
}
[HttpGet]
public async Task<IActionResult> AccountSettings()
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") != Guid.Empty)
{
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var user = await _userManager.FindByNameAsync(currentUser.UserName);
AccountSettings model = new AccountSettings();
List<SelectListItem> List = _customerService.GetCustomerReminderQuestions();
model.Reminder_Question_List = List;
model.Email = Convert.ToString(user.Email);
return View(model);
}
else
{
return LocalRedirect("~/Identity/Account/Login");
}
}
[HttpPost]
public async Task<IActionResult> AccountSettings(AccountSettings Account_Setting_Data)
{
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var user = await _userManager.FindByNameAsync(currentUser.UserName);
bool Result = false;
if (user != null)
{
if (!string.IsNullOrEmpty(Account_Setting_Data.Email) && !string.IsNullOrEmpty(Account_Setting_Data.Password))
{
user.Email = Account_Setting_Data.Email;
user.PasswordHash = _passwordHasher.HashPassword(user, Account_Setting_Data.Password);
user.FK_Reminder_Question = Account_Setting_Data.Reminder_Question == null ? user.FK_Reminder_Question : Convert.ToInt32(Account_Setting_Data.Reminder_Question);
user.Answer = Account_Setting_Data.Answer == null ? user.Answer : Account_Setting_Data.Answer;
var identity = await _userManager.UpdateAsync(user);
if (identity.Succeeded)
Result = true;
}
}
return Json(Result);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
这里是homecontroller继承的basecontroller
using Project.Application.Entities;
using Project.Application.Interfaces;
using Project.Application.ViewModel;
using Project.Common;
using Project.Data.Data;
using Project.Data.Identity;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Project.Controllers
{
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public class BaseController : Controller
{
//private readonly ApplicationSignInManager _signInManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IUserAccessSecurityService _userAccessSecurityService;
private readonly IDataProtector _protector;
private readonly IUserSessionLogService _userSessionLogService;
//public BaseController(ApplicationSignInManager signInManager)
public BaseController(SignInManager<ApplicationUser> signInManager, IUserAccessSecurityService userAccessSecurityService, IDataProtectionProvider provider, IUserSessionLogService userSessionLogService)
{
_signInManager = signInManager;
_userAccessSecurityService = userAccessSecurityService;
_protector = provider.CreateProtector("Protector");
_userSessionLogService = userSessionLogService;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") == Guid.Empty)
{
_signInManager.SignOutAsync();
bool isAjaxCall = context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
if(isAjaxCall)
{
context.Result = new UnauthorizedResult();
}
else
{
var PK_ID = TempData["UserLogId"];
if (Convert.ToInt32(PK_ID) > 0)
_userSessionLogService.InsertUpdateSession(0, Convert.ToInt32(PK_ID), "", "", new Guid());
context.Result = new RedirectResult("~/Identity/Account/Login");
}
return;
}
else
{
TempData["UserLogId"] = HttpContext.Session.GetObjectFromJson<int>("SessionId");
}
if (!HttpContext.Session.GetObjectFromJson<bool>("IsAdmin") && !string.IsNullOrEmpty(context.HttpContext.Request.Query["q"].ToString()))
{
//&& context.HttpContext.Request.QueryString.Value!=null && context.HttpContext.Request.QueryString.Value!=""
var currentUserId = HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId");
int CustomerId = HttpContext.Session.GetObjectFromJson<int>("CurrentCustomer");
var qs = context.HttpContext.Request.Query["q"].ToString();//context.HttpContext.Request.QueryString.Value; //HttpContext.Request.Query["q"];
var queryString = _protector.Unprotect(qs);
var parameters = ClsGeneral.GetParams(queryString);
var pageId = 0;
var tableName = "";
if (parameters.TryGetValue("PageId", out string value))
{
pageId = Convert.ToInt32(value);
}
if (parameters.TryGetValue("TableName", out value))
{
tableName = Convert.ToString(value);
}
List<GroupPagesRights> view_Group_Page_Rights = _userAccessSecurityService.GetGroupPagesRightsByUser(CustomerId, currentUserId);
if (view_Group_Page_Rights == null || view_Group_Page_Rights.Count == 0 || (!view_Group_Page_Rights.Any(x => x.FK_Page == pageId)))
{
context.HttpContext.Response.Redirect(Url.Action("Unauthorised", "Home"));
}
}
base.OnActionExecuting(context);
}
}
}
请帮忙
谢谢
如果您在操作或 class 上没有 [Authorize]
,或者没有对用户进行身份验证的后备身份验证策略,则不会对用户进行身份验证。
我们可以在 SignIn
上加上 [Authorize]
,但这会破坏目的。
您还有另一种选择,手动验证并检查是否成功:
[HttpGet]
public async Task<ActionResult> SignIn()
{
var oktaResult = await HttpContext.AuthenticateAsync(OktaDefaults.MvcAuthenticationScheme);
if (oktaResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}
return Challenge(OktaDefaults.MvcAuthenticationScheme);
}
这里是 startup.cs 我已经按照以下配置了 okta openid connect。请审核
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)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOktaMvc(new OktaMvcOptions
{
// Replace these values with your Okta configuration
OktaDomain = Configuration.GetValue<string>("AppSettings:OktaDomain"),
ClientId = Configuration.GetValue<string>("AppSettings:ClientId"),
ClientSecret = Configuration.GetValue<string>("AppSettings:ClientSecret"),
Scope = new List<string> { "openid", "profile", "email" },
});
//services.AddAuthorization();
services.Configure<FormOptions>(x => x.ValueCountLimit = 8192);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
var lockoutOptions = new LockoutOptions()
{
AllowedForNewUsers = true,
DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5),
MaxFailedAccessAttempts = 3
};
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 0;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Lockout = lockoutOptions;
})
.AddEntityFrameworkStores<AmpCoreContext>().AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.LoginPath = new PathString("/Identity/Account/Login");
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(20); });
services
.AddControllersWithViews()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
// Maintain property names during serialization. See:
// https://github.com/aspnet/Announcements/issues/194
.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddHttpContextAccessor();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var culture = CultureInfo.CreateSpecificCulture("en-US");
var dateformat = new DateTimeFormatInfo
{
ShortDatePattern = "MM/dd/yyyy",
LongDatePattern = "MM/dd/yyyy hh:mm:ss tt"
};
culture.DateTimeFormat = dateformat;
var supportedCultures = new[] { culture };
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(culture),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
try
{
var context = serviceScope.ServiceProvider.GetRequiredService<AmpCoreContext>();
var customers = context.Customer.ToListAsync().Result;
string output =
Newtonsoft.Json.JsonConvert.SerializeObject(customers, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText("tenants.json", output);
}
catch (Exception)
{
throw;
}
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//app.UseCookiePolicy();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
这是我的帐户控制器,在登录按钮上单击我将其重定向到帐户控制器 singin 方法。但它总是在循环中调用。请检查下面的代码
public class AccountController : Controller
{
public IActionResult SignIn()
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
return Challenge(OktaDefaults.MvcAuthenticationScheme);
}
return RedirectToAction("Index", "Home");
}
[HttpPost]
public IActionResult SignOut()
{
return new SignOutResult(
new[]
{
OktaDefaults.MvcAuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme,
},
new AuthenticationProperties { RedirectUri = "/Home/" });
}
}
它重定向到 okta,okta return 但是 HttpContext.User.Identity.IsAuthenticated 在帐户控制器中总是错误的,它是无限循环。
这是家庭控制器
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using Project.Common;
using System;
using Microsoft.AspNetCore.Identity;
using Project.Data.Identity;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.DataProtection;
using Project.Application.Interfaces;
using Project.Application.ViewModel;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Data;
using Microsoft.AspNetCore.Http;
using Project.Data.Data;
using ErrorViewModel = Project.Models.ErrorViewModel;
using System.Linq;
using Okta.AspNetCore;
using Microsoft.AspNetCore.Authorization;
namespace Project.Controllers
{
[Authorize]
public class HomeController : BaseController
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ICustomerService _customerService;
private IPasswordHasher<ApplicationUser> _passwordHasher;
private readonly IFieldService _fieldService;
private IModuleService _moduleService;
private readonly IHttpContextAccessor _httpContextAccessor;
private ISession _session => _httpContextAccessor.HttpContext.Session;
private readonly IUserAccessSecurityService _userAccessSecurityService;
private readonly IGroupService _groupService;
private readonly Context _context;
private IDataProtectionProvider _provider;
private readonly IUserSessionLogService _userSessionLogService;
public HomeController(UserManager<ApplicationUser> userManager, ICustomerService customerService, IPasswordHasher<ApplicationUser> passwordHasher, IFieldService fieldService,
IModuleService moduleService, IUserAccessSecurityService userAccessSecurityService, IGroupService groupService, Context context, IHttpContextAccessor httpContextAccessor,
IDataProtectionProvider provider, SignInManager<ApplicationUser> signInManager, IUserSessionLogService userSessionLogService) : base(signInManager, userAccessSecurityService, provider, userSessionLogService)
{
_userManager = userManager;
_customerService = customerService;
_passwordHasher = passwordHasher;
_fieldService = fieldService;
_moduleService = moduleService;
_userAccessSecurityService = userAccessSecurityService;
_groupService = groupService;
_context = context;
_httpContextAccessor = httpContextAccessor;
_provider = provider;
_userSessionLogService = userSessionLogService;
}
public IActionResult unauthorised()
{
return View("~/Views/Home/AccessDenied.cshtml");
}
[Authorize]
public IActionResult Index()
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") != Guid.Empty)
{
var Fk_Customer = HttpContext.Session.GetObjectFromJson<int>("CurrentCustomer");
var FK_User = HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId");
bool hasGroup = false;
DashBoardViewModel dashBoardViewModel = new DashBoardViewModel();
List<ViewUserGroup> viewUserGroup = new List<ViewUserGroup>();
ApplicationUser appUsers = _context.Users.SingleOrDefault(x => x.Id == FK_User);
bool isSuperAdmin = _context.UserType.Where(x => x.ID == appUsers.FK_UserType && x.Type.ToLower() == "super admin").Any();
bool isAdmin = _context.UserType.Where(x => x.ID == appUsers.FK_UserType && x.Type.ToLower() == "company admin").Any();
viewUserGroup = _userAccessSecurityService.GetUserGroupByUser(Fk_Customer, FK_User);
if (viewUserGroup.Count > 0)
{
if (viewUserGroup[0].Fk_Group != 0 && viewUserGroup[0].PK_Group != 0)
hasGroup = true;
}
ViewBag.hasGroup = hasGroup;
ViewBag.isSuperAdmin = isSuperAdmin;
DataTable dtPendingAssetCount = _fieldService.GetPendingAssetCount(Convert.ToInt32(Fk_Customer), (isAdmin ? true : (isSuperAdmin) ? true : false), FK_User);
if (dtPendingAssetCount != null && dtPendingAssetCount.Rows.Count > 0)
{
dashBoardViewModel.AccountReminder.Pending_Valuation_Count = dtPendingAssetCount.Rows[0]["Pending_Valuation_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Valuation_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_New_Assets_Count = dtPendingAssetCount.Rows[0]["Pending_New_Assets_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_New_Assets_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Change_Request_Count = dtPendingAssetCount.Rows[0]["Pending_Change_Request_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Change_Request_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_New_Assets_State_Count = dtPendingAssetCount.Rows[0]["Pending_New_Assets_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_New_Assets_State_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Change_Request_State_Count = dtPendingAssetCount.Rows[0]["Pending_Change_Request_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Change_Request_State_Count"]) : 0;
dashBoardViewModel.AccountReminder.Pending_Valuation_State_Count = dtPendingAssetCount.Rows[0]["Pending_Valuation_State_Count"] != DBNull.Value ? Convert.ToInt32(dtPendingAssetCount.Rows[0]["Pending_Valuation_State_Count"]) : 0;
}
dashBoardViewModel.AccountReminder.New_Asset_Pending_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.New_Asset_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.AccountReminder.Pending_Change_Request_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.Change_request_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.AccountReminder.Pending_Valuation_State = _context.LookUp.Where(x => x.Field_Name.ToLower() == ConstantStrings.State_Of_Asset.ToLower() && x.Value.ToLower() == State_Of_Asset.Valuation_Pending.ToLower() && x.FK_Customer == Fk_Customer && !x.Is_Deleted).Select(x => x.PK_LookUp).FirstOrDefault();
dashBoardViewModel.PropertyRisk = _fieldService.GetNumberOfLocationDetails(Fk_Customer);
return View(dashBoardViewModel);
}
else
{
return LocalRedirect("~/Identity/Account/Login");
}
}
[HttpGet]
public async Task<IActionResult> AccountSettings()
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") != Guid.Empty)
{
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var user = await _userManager.FindByNameAsync(currentUser.UserName);
AccountSettings model = new AccountSettings();
List<SelectListItem> List = _customerService.GetCustomerReminderQuestions();
model.Reminder_Question_List = List;
model.Email = Convert.ToString(user.Email);
return View(model);
}
else
{
return LocalRedirect("~/Identity/Account/Login");
}
}
[HttpPost]
public async Task<IActionResult> AccountSettings(AccountSettings Account_Setting_Data)
{
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var user = await _userManager.FindByNameAsync(currentUser.UserName);
bool Result = false;
if (user != null)
{
if (!string.IsNullOrEmpty(Account_Setting_Data.Email) && !string.IsNullOrEmpty(Account_Setting_Data.Password))
{
user.Email = Account_Setting_Data.Email;
user.PasswordHash = _passwordHasher.HashPassword(user, Account_Setting_Data.Password);
user.FK_Reminder_Question = Account_Setting_Data.Reminder_Question == null ? user.FK_Reminder_Question : Convert.ToInt32(Account_Setting_Data.Reminder_Question);
user.Answer = Account_Setting_Data.Answer == null ? user.Answer : Account_Setting_Data.Answer;
var identity = await _userManager.UpdateAsync(user);
if (identity.Succeeded)
Result = true;
}
}
return Json(Result);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
这里是homecontroller继承的basecontroller
using Project.Application.Entities;
using Project.Application.Interfaces;
using Project.Application.ViewModel;
using Project.Common;
using Project.Data.Data;
using Project.Data.Identity;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Project.Controllers
{
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public class BaseController : Controller
{
//private readonly ApplicationSignInManager _signInManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IUserAccessSecurityService _userAccessSecurityService;
private readonly IDataProtector _protector;
private readonly IUserSessionLogService _userSessionLogService;
//public BaseController(ApplicationSignInManager signInManager)
public BaseController(SignInManager<ApplicationUser> signInManager, IUserAccessSecurityService userAccessSecurityService, IDataProtectionProvider provider, IUserSessionLogService userSessionLogService)
{
_signInManager = signInManager;
_userAccessSecurityService = userAccessSecurityService;
_protector = provider.CreateProtector("Protector");
_userSessionLogService = userSessionLogService;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId") == Guid.Empty)
{
_signInManager.SignOutAsync();
bool isAjaxCall = context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
if(isAjaxCall)
{
context.Result = new UnauthorizedResult();
}
else
{
var PK_ID = TempData["UserLogId"];
if (Convert.ToInt32(PK_ID) > 0)
_userSessionLogService.InsertUpdateSession(0, Convert.ToInt32(PK_ID), "", "", new Guid());
context.Result = new RedirectResult("~/Identity/Account/Login");
}
return;
}
else
{
TempData["UserLogId"] = HttpContext.Session.GetObjectFromJson<int>("SessionId");
}
if (!HttpContext.Session.GetObjectFromJson<bool>("IsAdmin") && !string.IsNullOrEmpty(context.HttpContext.Request.Query["q"].ToString()))
{
//&& context.HttpContext.Request.QueryString.Value!=null && context.HttpContext.Request.QueryString.Value!=""
var currentUserId = HttpContext.Session.GetObjectFromJson<Guid>("CurrentUserId");
int CustomerId = HttpContext.Session.GetObjectFromJson<int>("CurrentCustomer");
var qs = context.HttpContext.Request.Query["q"].ToString();//context.HttpContext.Request.QueryString.Value; //HttpContext.Request.Query["q"];
var queryString = _protector.Unprotect(qs);
var parameters = ClsGeneral.GetParams(queryString);
var pageId = 0;
var tableName = "";
if (parameters.TryGetValue("PageId", out string value))
{
pageId = Convert.ToInt32(value);
}
if (parameters.TryGetValue("TableName", out value))
{
tableName = Convert.ToString(value);
}
List<GroupPagesRights> view_Group_Page_Rights = _userAccessSecurityService.GetGroupPagesRightsByUser(CustomerId, currentUserId);
if (view_Group_Page_Rights == null || view_Group_Page_Rights.Count == 0 || (!view_Group_Page_Rights.Any(x => x.FK_Page == pageId)))
{
context.HttpContext.Response.Redirect(Url.Action("Unauthorised", "Home"));
}
}
base.OnActionExecuting(context);
}
}
}
请帮忙
谢谢
如果您在操作或 class 上没有 [Authorize]
,或者没有对用户进行身份验证的后备身份验证策略,则不会对用户进行身份验证。
我们可以在 SignIn
上加上 [Authorize]
,但这会破坏目的。
您还有另一种选择,手动验证并检查是否成功:
[HttpGet]
public async Task<ActionResult> SignIn()
{
var oktaResult = await HttpContext.AuthenticateAsync(OktaDefaults.MvcAuthenticationScheme);
if (oktaResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}
return Challenge(OktaDefaults.MvcAuthenticationScheme);
}