Сценарий:
Я реализую asp.net core 3.1 MVC
проект. Я авторизую своего пользователя через службу ldap
Active Directory. Пользователь успешно проходит аутентификацию и заходит на мой сайт. но после нажатия на каждый пункт меню, чтобы увидеть соответствующий индекс контроллера, он показывает белую страницу. Я написал поверх всего моего ключевого слова класса контроллера [Authorize], чтобы позволить любому авторизованному пользователю видеть все контроллеры.
Моя проблема:
, когда пользователь нажимает на каждый пункт меню в доме чтобы увидеть индекс соответствующего контроллера, он показывает белую страницу, а когда я публикую sh мой проект на сервере ldap, он показывает ошибку 404. Я ценю, если кто-нибудь может предложить мне решение. Кажется, у маршрутизации есть проблемы, но я не уверен. Я даже написал поверх моего класса контроллера ключевое слово [AllowAnonymous], но все же вижу белые страницы для страниц индекса для каждого контроллера. Должен ли я что-нибудь добавить в startup.cs для AutheticationHelper или CustomAuthenticationMiddleware в качестве службы?
Вот мой метод входа в контроллере учетной записи
namespace CSDDashboard.Controllers
{
[Route("[controller]/[action]")]
[AllowAnonymous]
public class AccountController : Controller
{
private readonly LdapUserManager _userManager;
private readonly LdapSignInManager _signInManager;
private readonly ILogger _logger;
public AccountController(
LdapUserManager userManager,
LdapSignInManager signInManager,
ILogger<AccountController> logger)
{
this._userManager = userManager;
this._signInManager = signInManager;
this._logger = logger;
}
[AllowAnonymous]
[HttpGet]
public async Task<IActionResult> Signin(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await this.HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
this.ViewData["ReturnUrl"] = returnUrl;
return this.View();
}
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Signin(SigninViewModel model, string returnUrl = null)
{
this.ViewData["ReturnUrl"] = returnUrl;
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "tehran.iri"))
{
// validate the user's credentials
//var result = ctx.ValidateCredentials(model.UserName, model.Password);
// try {
if (ctx.ValidateCredentials(model.UserName, model.Password))
{
// credentials are OK --> allow user in
HttpContext.Session.MarkAsAuthenticated(model.UserName);
//Added recently
Debug.Writeline(string.Format("Redirection to {0}", returnUrl);
return RedirectToLocal(returnUrl);
}
else
{
this.TempData["ErrorMessage"] = "The username and/or password are incorrect!";
return this.View(model);
// credentials aren't OK --> send back error message
}
}
}}}
Вот мой класс промежуточного программного обеспечения и класс AuthenticationHelper
public static class AuthenticationHelper
{
private const string SessionKey = "AuthenticationHelper.UserName";
public static void MarkAsAuthenticated(this Microsoft.AspNetCore.Http.ISession session, string authenticatedUserName)
{
session.SetString(SessionKey, authenticatedUserName);
}
public static ClaimsPrincipal GetAuthenticatedUser(this Microsoft.AspNetCore.Http.ISession session)
{
string authenticatedUserName = session.GetString(SessionKey);
if (string.IsNullOrEmpty(authenticatedUserName)) return null;
return new GenericPrincipal(new GenericIdentity(authenticatedUserName), Array.Empty<string>());
}
}
public class CustomAuthenticationMiddleware
{
private readonly RequestDelegate _next;
public CustomAuthenticationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
ClaimsPrincipal user = context.Session.GetAuthenticatedUser();
if (user != null) context.User = user;
await _next(context);
}
}
public static class CustomAuthenticationMiddlewareExtensions
{
public static IApplicationBuilder UseCustomAuthentication(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CustomAuthenticationMiddleware>();
}
}
Вот мой код в statrup.cs:
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.Configure<LdapSettings>(Configuration.GetSection("LdapSettings"));
services.AddDbContext<LdapDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("CSDDashboardContext")));
//-------------------------------------------------
services.AddIdentity<LdapUser, IdentityRole>()
.AddEntityFrameworkStores<LdapDbContext>()
.AddUserManager<LdapUserManager>()
.AddSignInManager<LdapSignInManager>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "CSDDashboard";
options.LoginPath = "/Account/Signin"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = "/Account/Signout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = true;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
});
services.AddRazorPages();
services.AddTransient<ILdapService, LdapService>();
//-------------------------------------------------
services.AddControllersWithViews();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);//We set Time here
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddDistributedMemoryCache();
//Notice this is NOT the same class... Assuming this is a valid DBContext. You need to add this class as well.
services.AddDbContext<CSSDDashboardContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("CSDDashboardContext")));
services.AddDbContext<CSDDashboardContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("CSDDashboardContext")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// app.UseDeveloperExceptionPage(options);
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.UseSession();
app.UseRouting();
app.UseCustomAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
//Here are all of my controllers, but as it seems just I can uncomment one controller pattern here, I commented all the others
// pattern: "{controller=Applications}/{action=Index}/{id?}");
//pattern: "{controller=Home}/{action=Index}/{id?}");
// pattern: "{controller=ApiApplications}/{action=Index}/{id?}");
pattern: "{controller=Gates}/{action=Index}/{id?}");