ElenaRez Ответов: 1

Проблема в маршрутизации URL-адреса контроллера после авторизации


Сценарий:

Я внедряю asp.net основной проект 3.1 MVC. Я авторизую своего пользователя через службу ldap Active Directory. Пользователь успешно проходит аутентификацию и входит на мой сайт. но после нажатия на каждый пункт меню, чтобы увидеть соответствующий индекс контроллера, он показывает белую страницу. Я написал поверх всего своего класса контроллеров [Authorize] ключевое слово для того, чтобы любой авторизованный пользователь мог видеть все контроллеры.

Моя проблема заключается в том, что когда пользователь нажимает на каждый пункт меню в home, чтобы увидеть соответствующий индекс контроллера, он показывает белую страницу, а когда я публикую свой проект на сервере ldap, он показывает мне ошибку 404. Я буду признателен, если кто-нибудь предложит мне решение. Мне кажется, что у маршрутизации есть проблемы, но я не уверен. в моем меню есть пункты для Home index controller, Application index controller, ApiApplication index controller и Gate index controller, и хотя поверх Home controller, как и другие, я написал [Authorize] ключевое слово, если пользователь нажимает на его пункт меню, он не показывает белую страницу и работает правильно, но другие показывают белую страницу. Я даже написал поверх своих классов контроллеров ключевое слово [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);
                    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
                }
            }
        }
    }
}
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>();
    }
}
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)
    {
        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?}");
        });
    }
}

Richard Deeming

NB: Вам не нужно перечислять все ваши контроллеры в списке. MapControllerRoute вызов. Вы определяете шаблон для маршрута и значения после него = это просто значения по умолчанию.

pattern: "{controller=Home}/{action=Index}/{id?}"

будет соответствовать:
* /AnyController/AnyAction/AnyId
* /AnyController/AnyAction
* /AnyController (по умолчанию используется Index действие на этом контроллере)
* / (по умолчанию используется Index действие на HomeController)

Маршрутизация к действиям контроллера в ASP.NET ядро | Microsoft Docs[^]

1 Ответов

Рейтинг:
1

KarstenK

404-это ошибка "ресурс не найден".

Похоже, что запрошенный вами ресурс не может быть найден. Причиной могут быть отсутствующие права, плохо сформированные или неполные строки пути.

Совет: используйте UNC-патхи


ElenaRez

Спасибо за ваш ответ. Не могли бы вы объяснить, как я могу использовать UNC-пути?