Измените redirectURI и CallbackPath для аутентификации AzureAD в. net core 3.1.1 веб-приложении - PullRequest
0 голосов
/ 25 апреля 2020

Я создал новое веб-приложение. net core 3.1.1 с платформой Razor Pages. При создании приложения я установил Аутентификацию по умолчанию как AzureAd. Когда я запускаю приложение, аутентификация работает просто отлично. Сгенерированный файл appsettings выглядит следующим образом:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myDomain",
    "TenantId": "myTenantId",
    "ClientId": "myClientId",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Я создал новый контроллер в своем приложении, который выглядит очень просто, например:

namespace WebApplication1.Controllers
{
    public class AccountController : Controller
    {
        [HttpGet]
        public void SignIn()
        {
           //here comes the logic which checks in what role is the logged User
           //the role management stuff will be implemented in the app
        }
    }
}

Так выглядит мой Startup.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.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));
        services.AddMvc(options =>
        {
            options.EnableEndpointRouting = false;
        });
        services.AddRazorPages().AddMvcOptions(options =>{});
    }

    // 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("/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.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
        });

        app.UseMvc(routes =>
       {
            routes.MapRoute(
            name: "default",
            template: "{controller=Account}/{action=SignIn}");
       });
    }
}

Я хотел бы иметь возможность изменить AzureAd / CallbackPath на что-то отличное от "/ signin-oid c", например. Я хотел бы изменить его на Account / SignIn. Затем я хотел бы перехватить обратный вызов из azure и на основании адреса электронной почты зарегистрированного пользователя я хотел бы изменить токен, добавив некоторые системные роли и сделать перенаправление на соответствующую страницу панели мониторинга в зависимости от роли пользователя. Для администратора и клиента может быть другая панель управления.

Поэтому я попытался изменить "CallbackPath": "/Account/SignIn", и я также обновил RedirectURI в Azure: RedirectURI in Azure

Затем я снова запускаю приложение, устанавливаю точку останова в void SignIn(), снова захожу в систему и вместо нажатия /Account/SignIn меня просто перенаправили на главную страницу, the https://localhost:44321. Я также попытался вручную запустить https://localhost:44321/Account/SignIn в браузере и увидел следующее сообщение об ошибке:

An unhandled exception occurred while processing the request.
Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.

enter image description here

Я попытался проверить, что-то есть в документации , но я не нашел ничего полезного. Любые идеи о том, что я должен сделать, чтобы это работало? Приветствия

РЕДАКТИРОВАТЬ:

Я также использую Microsoft.AspNetCore.Authentication.AzureAD.UI рамки.

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

CallbackPath - это путь, по которому сервер будет перенаправлять во время аутентификации. Он автоматически обрабатывается самим промежуточным программным обеспечением OID C, это означает, что мы не можем контролировать logi c, создав новый контроллер / действие и установив для него CallbackPath. Ниже приведен общий процесс:

Во время аутентификации весь процесс контролируется промежуточным программным обеспечением OpenID Connect, после того как пользователь подтвердит учетные данные на странице входа в систему Azure, Azure Объявление перенаправит пользователя обратно на перенаправление вашего приложения. url, который установлен в конфигурации OID C, так что вы можете получить код авторизации (если используется поток кода) и завершить процесс аутентификации. После аутентификации пользователь будет перенаправлен на URL-адрес перенаправления.

на основе адреса электронной почты зарегистрированного пользователя. Я хотел бы изменить токен, чтобы добавить некоторые системные роли и сделать перенаправление на соответствующую панель инструментов. страница на основе роли пользователя. Для администратора и клиента может быть другая панель управления.

Во-первых, вы не можете изменить токен, и вам не нужно его изменять.

Вы можете использовать события уведомлений в OID C OWIN Middlerware, который активирует контроль разработчика над процессом аутентификации. OnTokenValidated предлагает вам возможность изменить ClaimsIdentity, полученный из входящего токена, вы можете запросить роль пользователя на основе идентификатора пользователя из локальной базы данных и добавить к заявкам пользователя:

 services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));


services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
    options.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = ctx =>
        {
            //query the database to get the role

            // add claims
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Role, "Admin")
            };
            var appIdentity = new ClaimsIdentity(claims);

            ctx.Principal.AddIdentity(appIdentity);

            return Task.CompletedTask;
        },
    };
});

Затем в контроллере вы можете получить утверждение как:

var role = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value;

Затем вы можете отфильтровать действия на основе указанной c заявки.

Если вы хотите перенаправить пользователя на указанный c маршрут / страницу после аутентификации установите URL-адрес на AuthenticationProperties:

if (!User.Identity.IsAuthenticated)
{
    return Challenge(new AuthenticationProperties() { RedirectUri = "/home/redirectOnRole" } , AzureADDefaults.AuthenticationScheme);
}  

И по этому пути вы можете перенаправить пользователя в зависимости от роли пользователя.

0 голосов
/ 28 апреля 2020

Благодаря ответу Nan Yo мне удалось установить sh перенаправление на нужный мне маршрут после входа в систему через AzureAd, а также мне удалось перенаправить на нужную страницу на основе роль зарегистрированного пользователя.

Я изменил _LoginPartial так:

@using HighElo.Web.Extensions
<ul class="navbar-nav">
    @if (User.Identity.IsAuthenticated)
    {
        <li class="nav-item">
            <span class="navbar-text text-dark">Logged as: <b>@User.GetEmail()</b></span>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="AzureAD" asp-controller="Account" asp-action="SignOut">Sign out</a>
        </li>
    }
    else
    {
        <li class="nav-item">

            <a class="nav-link text-dark" href="/Account/SignIn">Sign in</a>
        </li>
    }
</ul>

Я создал новый контроллер в моем каталоге root, который выглядит следующим образом:

[AllowAnonymous]
public class AccountController : Controller
{
    [Route("Account/SignIn")]
    public IActionResult SignIn()
    {
        if (!User.Identity.IsAuthenticated)
        {
            return Challenge(new AuthenticationProperties() { RedirectUri = "/Account/Callback" }, AzureADDefaults.AuthenticationScheme);
        }

        return Forbid();
    }

    [Authorize]

    public IActionResult Callback()
    {
        if (User.IsInRole("Client"))
        {
            //redirect to the Clients area
            return LocalRedirect("/Clients/Dashboard");
        }
        //here comes other role checks

        return Forbid();
    }
}
...