C# 在.net core 3.1.1 web app中更改AzureAD身份验证的重定向URI和回调路径
我使用Razor Pages框架创建了一个新的.net core 3.1.1 web应用程序。 创建应用程序时,我将默认身份验证设置为AzureAd。 当我运行应用程序时,身份验证工作正常。 生成的appsettings文件如下所示: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", "
{
"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();
}
}