Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net core 3.1.1 web app中更改AzureAD身份验证的重定向URI和回调路径_C#_Authentication_Asp.net Core_Azure Active Directory_Asp.net Core 3.1 - Fatal编程技术网

C# 在.net core 3.1.1 web app中更改AzureAD身份验证的重定向URI和回调路径

C# 在.net core 3.1.1 web app中更改AzureAD身份验证的重定向URI和回调路径,c#,authentication,asp.net-core,azure-active-directory,asp.net-core-3.1,C#,Authentication,Asp.net Core,Azure Active Directory,Asp.net Core 3.1,我使用Razor Pages框架创建了一个新的.net core 3.1.1 web应用程序。 创建应用程序时,我将默认身份验证设置为AzureAd。 当我运行应用程序时,身份验证工作正常。 生成的appsettings文件如下所示: { "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "myDomain", "TenantId": "myTenantId", "

我使用Razor Pages框架创建了一个新的.net core 3.1.1 web应用程序。 创建应用程序时,我将默认身份验证设置为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": "*"
}
[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();
    }
}
我在我的应用程序中创建了一个新的控制器,看起来非常简单,就像:

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 oidc不同的内容,例如,我希望将其更改为Account/signin。然后,我想捕获来自azure的回调呼叫,并根据记录的用户电子邮件地址修改令牌以添加一些系统角色,并根据用户角色重定向到相应的仪表板页面。管理员和客户端可以有不同的仪表板

因此,我尝试更改CallbackPath:/Account/sign,并在Azure中更新了RedirectURI:

然后我再次运行应用程序,在void-SignIn中设置一个断点,我再次登录,我没有点击/Account/SignIn,而是被重定向到主页面https://localhost:44321. 我还尝试手动运行https://localhost:44321/Account/SignIn 在浏览器中,我看到以下错误消息:

An unhandled exception occurred while processing the request.
Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
我试着检查一下里面是否有什么东西,但我没有发现任何有用的东西。 我该怎么做才能让它工作呢? 干杯

编辑:

我还使用Microsoft.AspNetCore.Authentication.AzureAD.UI框架。

回调路径是服务器在身份验证期间重定向的路径。它是由OIDC中间件本身自动处理的,这意味着我们不能通过创建新的控制器/操作并设置回调路径来控制逻辑。以下是一般流程:

在身份验证期间,整个过程由OpenID Connect中间件控制,当用户在Azure的登录页面中验证凭据后,Azure Ad将用户重定向回在OIDC配置中设置的应用程序重定向url,因此,您可以使用代码流获取授权代码IF并完成身份验证过程。身份验证之后,用户将被重定向到重定向url

根据记录的用户电子邮件地址,我想修改令牌以添加一些系统角色,并根据用户角色重定向到相应的仪表板页面。管理员和客户端可以有不同的仪表板

第一件事是你不能修改令牌,你不需要修改它

您可以在OIDC OWIN Middlerware中使用通知事件,该事件调用以启用开发人员对身份验证过程的控制。OnTokenValidated为您提供了修改从传入令牌获得的ClaimsEntity的机会,您可以根据本地数据库中的用户id查询用户角色,并添加到用户声明中:

 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;
        },
    };
});
然后,您可以根据特定声明筛选操作

如果要在身份验证后将用户重定向到特定路由/页面,请将url置于AuthenticationProperties:

在该路径中,您可以根据用户的角色重定向用户。

回调路径是服务器在身份验证期间重定向的路径。它是由OIDC中间件本身自动处理的,这意味着我们不能通过创建新的控制器/操作并设置回调路径来控制逻辑。以下是一般流程:

在身份验证期间,整个过程由OpenID Connect中间件控制,当用户在Azure的登录页面中验证凭据后,Azure Ad将用户重定向回在OIDC配置中设置的应用程序重定向url,因此,您可以使用代码流获取授权代码IF并完成身份验证过程。身份验证之后,用户将被重定向到重定向url

根据记录的用户电子邮件地址,我想修改令牌以添加一些系统角色,并根据用户角色重定向到相应的仪表板页面。管理员和客户端可以有不同的仪表板

第一件事是你不能修改令牌,你不需要修改它

您可以在OIDC OWIN Middlerware中使用通知事件,该事件调用以启用开发人员对身份验证过程的控制。OnTokenValidated为您提供了修改从传入令牌获得的ClaimsEntity的机会,您可以根据本地数据库中的用户id查询用户角色,并添加到用户声明中:

 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;
        },
    };
});
然后,您可以根据特定声明筛选操作

如果要在身份验证后将用户重定向到特定路由/页面,请将url置于AuthenticationProperties:

在该路径中,您可以根据用户的角色重定向用户。

多亏了这个答案,在我通过AzureAd登录之后,我成功地建立了一个重定向到我想要的路由的路径,并且我还成功地进行了 根据登录用户的角色重定向到正确的页面

我将_LoginPartial修改为:

多亏了这个答案,我在通过AzureAd登录后成功地建立了到我想要的路由的重定向,并且还根据登录用户的角色成功地重定向到正确的页面

我将_LoginPartial修改为:


我应该把if放在哪里!User.Identity.IsAuthenticated{return Challengenew AuthenticationProperties{RedirectUri=/home/redirectOnRole},AzureADDefaults.AuthenticationScheme;}是否已从您的答案中验证?用户来自Microsoft.AspNetCore.Mvc.Razor,因此我不确定是否可以在中间件中执行此操作?我还使用Microsoft.AspNetCore.Authentication.AzureAD.UI,因此重定向到AzureAD登录页面通过此框架进行。我刚刚尝试添加wait context.HttpContext.ChallengeAsyncAzureADDefaults.AuthenticationScheme,新的AuthenticationProperties{RedirectUri=/contact};到OnTokenValidated但重定向在我重新登录用户后不起作用:不,该代码应在一个操作中触发身份验证。我的代码示例还使用Microsoft.AspNetCore.authentication.AzureAD.UI;图书馆你有两个选择:1。认证后,用户将被重定向到索引页面,然后您可以根据用户在索引操作中的角色重定向用户,我提供了如何在上面添加角色声明的代码示例。我应该在哪里放置if!User.Identity.IsAuthenticated{return Challengenew AuthenticationProperties{RedirectUri=/home/redirectOnRole},AzureADDefaults.AuthenticationScheme;}是否已从您的答案中验证?用户来自Microsoft.AspNetCore.Mvc.Razor,因此我不确定是否可以在中间件中执行此操作?我还使用Microsoft.AspNetCore.Authentication.AzureAD.UI,因此重定向到AzureAD登录页面通过此框架进行。我刚刚尝试添加wait context.HttpContext.ChallengeAsyncAzureADDefaults.AuthenticationScheme,新的AuthenticationProperties{RedirectUri=/contact};到OnTokenValidated但重定向在我重新登录用户后不起作用:不,该代码应在一个操作中触发身份验证。我的代码示例还使用Microsoft.AspNetCore.authentication.AzureAD.UI;图书馆你有两个选择:1。认证后,用户将被重定向到索引页面,然后可以根据用户在索引操作中的角色重定向用户,我提供了如何在上面添加角色声明的代码示例。
@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>
[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();
    }
}