Gol*_*Age 1 c# authentication azure-active-directory asp.net-core 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",
"ClientId": "myClientId",
"CallbackPath": "/signin-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Run Code Online (Sandbox Code Playgroud)
我在我的应用程序中创建了一个新的控制器,它看起来非常简单,就像:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我的 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}");
});
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够将 AzureAd/CallbackPath 更改为与“/signin-oidc”不同的内容,例如。我想将其更改为帐户/登录。然后我想捕获来自 azure 的回调调用,并根据记录的用户电子邮件地址修改令牌以添加一些系统角色并根据用户角色重定向到适当的仪表板页面。管理员和客户可以有不同的仪表板。
所以我尝试更改"CallbackPath": "/Account/SignIn"并更新了 Azure 中的 RedirectURI:

然后我再次运行该应用程序,在 中设置断点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.
Run Code Online (Sandbox Code Playgroud)
我尝试检查文档中是否有内容,但没有发现任何有用的内容。关于我应该做什么才能使其发挥作用有什么想法吗?干杯
编辑:
我也用Microsoft.AspNetCore.Authentication.AzureAD.UI框架。
这CallbackPath是服务器在身份验证期间重定向的路径。它由 OIDC 中间件本身自动处理,这意味着我们无法通过创建新的控制器/操作并设置CallbackPath为它来控制逻辑。以下是一般流程:
在身份验证期间,整个过程由 OpenID Connect 中间件控制,用户在 Azure 登录页面验证凭据后,Azure Ad 会将用户重定向回 OIDC 配置中设置的应用程序重定向 URL,以便您获取授权代码(如果使用代码流)并完成身份验证过程。身份验证后,用户将被重定向到重定向 url。
基于登录的用户电子邮件地址,我想修改令牌以添加一些系统角色并根据用户角色重定向到适当的仪表板页面。管理员和客户可以有不同的仪表板。
第一件事是您不能修改令牌,也不需要修改它。
您可以在 OIDC OWIN Middlerware 中使用通知事件,它调用以使开发人员能够控制身份验证过程。 OnTokenValidated为您提供修改从传入令牌获得的 ClaimsIdentity 的机会,您可以根据本地数据库中的用户 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;
},
};
});
Run Code Online (Sandbox Code Playgroud)
然后在控制器中,您可以获得如下声明:
var role = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value;
Run Code Online (Sandbox Code Playgroud)
然后您可以根据特定声明过滤操作。
如果您想在身份验证后将用户重定向到特定的路由/页面,请将 url 设置为AuthenticationProperties:
if (!User.Identity.IsAuthenticated)
{
return Challenge(new AuthenticationProperties() { RedirectUri = "/home/redirectOnRole" } , AzureADDefaults.AuthenticationScheme);
}
Run Code Online (Sandbox Code Playgroud)
在该路径中,您可以根据用户的角色重定向用户。
| 归档时间: |
|
| 查看次数: |
5067 次 |
| 最近记录: |