- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个程序,该程序允许用户以两种方式进行身份验证。他们可以通过任何电子邮件创建和使用本地(自制)帐户;或者他们可以仅对我们的组织使用 Azure AD OAuth。无论使用哪种身份验证方法,都应同等对待用户,并在 context.User.Identity.IsAuthenticated
上返回 true。
我遇到了仅 Azure AD 方法有效的问题,为了解决此问题,我使用了身份验证策略 inspired by this article 。然而,在遵循它之后,两种身份验证方法似乎都不起作用:(
以下是 startup.cs
中的服务代码:
services.AddJwtAuthorization();
services.AddAuthentication(o =>
{
o.DefaultScheme = "MultiAuthSchemes";
o.DefaultChallengeScheme = "MultiAuthSchemes";
})
.AddCookie(o =>
{
o.LoginPath = "/login";
})
.AddJwtBearer("HomebrewScheme", _ => { })
.AddPolicyScheme("MultiAuthSchemes", JwtBearerDefaults.AuthenticationScheme, options =>
{
options.ForwardDefaultSelector = context =>
{
string authorization = context.Request.Headers[HeaderNames.Authorization];
if (!string.IsNullOrEmpty(authorization) && authorization.Contains("Bearer "))
{
var token = authorization["Bearer ".Length..].Trim();
var jwtHandler = new JwtSecurityTokenHandler();
return jwtHandler.CanReadToken(token)
? "HomebrewScheme" : "AdScheme";
}
return CookieAuthenticationDefaults.AuthenticationScheme;
};
})
.AddMicrosoftIdentityWebApi(Config, "AzureAd", "AdScheme");
services.AddAuthorization(o =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme,
"HomebrewScheme", "AdScheme");
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
o.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
var onlySecondJwtSchemePolicyBuilder = new AuthorizationPolicyBuilder("HomebrewScheme");
o.AddPolicy("OnlyHomebrewScheme", onlySecondJwtSchemePolicyBuilder
.RequireAuthenticatedUser()
.AddAuthenticationSchemes()
.Build());
var onlyCookieSchemePolicyBuilder = new AuthorizationPolicyBuilder("AdScheme");
o.AddPolicy("OnlyAdScheme", onlyCookieSchemePolicyBuilder
.RequireAuthenticatedUser()
.Build());
});
以下是 startup.cs
中的应用代码:
app.UseAuthentication()
app.UseGraphQLPlayground(new PlaygroundOptions
{
GraphQLEndPoint = GraphQLApiEndpoint
});
app.UseWebSockets();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(x => x.MapGraphQL(path: GraphQLApiEndpoint));
这是 startup.cs
中的代码,我用它来测试身份验证:
app.Use((context, next) =>
{
//Grab the first identity because the authentication type does not matter
if (context.User.Identity?.IsAuthenticated == true)
{
PermissionLevel = Permissions.Authorized;
}
});
从调试中可以看出,系统从未检测到我现在获得了身份验证。我知道前端可以正常工作,因为如果我仅使用 services.AddMicrosoftIdentityWebApiAuthentication(Config, "AzureAd", "AdScheme");
无论它是否是默认方案,一切都会正常。
感谢您的帮助,一直在解决这个问题😊
最佳答案
首先,我关注了this blog在我的代码中添加 Cookie 身份验证。它提供了一个登录页面让我们登录。并且在AccountController中,它提供了几个模拟用户帐户,以便我们可以使用它们来登录进行测试。
然后,我在登录页面中添加了代码,以便提供使用 AAD 登录的选项。
更改 Program.cs
文件以添加多个身份验证方案。
这是我的代码,Program.cs
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
//set CookieAuthenticationDefaults.AuthenticationScheme as the default authentication scheme
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x => x.LoginPath = "/account/login");
builder.Services.AddAuthentication()
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"), OpenIdConnectDefaults.AuthenticationScheme, "ADCookies");
// Add microsoft sign in page
builder.Services.AddControllersWithViews().AddMicrosoftIdentityUI();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
我的家庭 Controller
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using WebAppMvcCookieAuthAad.Models;
namespace WebAppMvcCookieAuthAad.Controllers
{
[AllowAnonymous]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[Authorize]
public async Task<IActionResult> ConfidentialDataAsync()
{
return View();
}
}
}
我的帐户 Controller :
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using WebAppMvcCookieAuthAad.Models;
namespace WebAppMvcCookieAuthAad.Controllers
{
public class AccountController : Controller
{
public List<UserModel> users = null;
public AccountController()
{
users = new List<UserModel>();
users.Add(new UserModel()
{
UserId = 1,
Username = "Tiny",
Password = "123",
Role = "Admin"
});
users.Add(new UserModel()
{
UserId = 2,
Username = "Other",
Password = "123",
Role = "User"
});
}
public IActionResult Login(string ReturnUrl = "/")
{
LoginModel objLoginModel = new LoginModel();
objLoginModel.ReturnUrl = ReturnUrl;
return View(objLoginModel);
}
[HttpPost]
public async Task<IActionResult> Login(LoginModel objLoginModel)
{
if (ModelState.IsValid)
{
var user = users.Where(x => x.Username == objLoginModel.UserName && x.Password == objLoginModel.Password).FirstOrDefault();
if (user == null)
{
ViewBag.Message = "Invalid Credential";
return View(objLoginModel);
}
else
{
var claims = new List<Claim>() {
new Claim(ClaimTypes.NameIdentifier, Convert.ToString(user.UserId)),
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Role, user.Role),
new Claim("FavoriteDrink", "Tea")
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
{
IsPersistent = objLoginModel.RememberLogin
});
return LocalRedirect(objLoginModel.ReturnUrl);
}
}
return View(objLoginModel);
}
public async Task<IActionResult> LogOut()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return LocalRedirect("/");
}
}
}
我的登录模型和用户模型
using System.ComponentModel.DataAnnotations;
namespace WebAppMvcCookieAuthAad.Models
{
public class LoginModel
{
[Required]
[Display(Name = "Username")]
public string UserName{get;set;}
[Required]
[DataType(DataType.Password)]
public string Password{get;set;}
public bool RememberLogin{get;set;}
public string ReturnUrl{get;set;}
}
}
namespace WebAppMvcCookieAuthAad.Models
{
public class UserModel
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Role { get; set; }
}
}
查看 -> 帐户 -> Login.cshtml:
@model WebAppMvcCookieAuthAad.Models.LoginModel
@{
ViewData["Title"] = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Login">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
@if (!string.IsNullOrEmpty(ViewBag.Message))
{
<span class="text-danger">
@ViewBag.Message
</span>
}
@Html.HiddenFor(x => x.ReturnUrl)
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input asp-for="RememberLogin" /> @Html.DisplayNameFor(model => model.RememberLogin)
</label>
</div>
</div>
<div class="form-group">
<input type="submit" value="Login" />
</div>
</form>
</div>
</div>
<div>
<label>sign in with aad</label>
<a asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in with aad</a>
</div>
查看 -> 主页 -> ConfidentialData.cshtml
@if(User.Identity.IsAuthenticated){
<table>
@foreach (var item in User.Claims)
{
<tr><td>@item.Type</td><td>@item.Value</td></tr>
}
</table>
}
View -> Shared -> _LoginPartial.cshtml,请不要忘记将此部分 View 添加到布局中。
@using System.Security.Principal
<ul class="navbar-nav">
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<span class="navbar-text text-dark">Hello @User.Identity.Name!</span>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-controller="Account" asp-action="LogOut">log out</a>
</li>
@*asp - area = "MicrosoftIdentity"*@
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-controller="Account" asp-action="Login">log in</a>
</li>
}
</ul>
appsetting.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "tenant_name",
"TenantId": "tenant_id",
"ClientId": "azure_ad_app_id",
"ClientSecret": "azure_ad_client_secret",
"CallbackPath": "/home", //don't forget to set redirect url in azure portal
"SignedOutCallbackPath ": "/signout-callback-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
这段代码在我这边运行良好,我可以使用 cookie auth 和 aad 登录。我注意到使用 aad 签名后,@User.Identity.Name
将不会显示用户名。但实际上登录流程成功了。
关于c# - ASP.NET核心6 : permit Azure AD authentication and local authentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73760373/
我试图对 ASP.Net MVC 有一个高层次的理解,我开始意识到它看起来很像原始的 ASP 脚本。过去,我们将“模型”/业务逻辑代码组织到 VBScript 类或 VB COM 组件中。 当然,现在
我已经搜索了一段时间,但似乎找不到答案。 我想在我的旋转木马中显示一个计数器,左边是当前项目(工作),左边是项目总数。 我的代码:
. 最佳答案 Scott Gu 称这些为代码块。这就是我的看法。 http://weblogs.asp.net/scottgu/archive/2010/04/06/new-lt-gt-syntax
我有一个使用 Visual Studio 2010/.net 4/VB 制作的网站。 我真的很喜欢我发现的 FAQ 系统的布局,因为它很简单,但它是经典的 asp。所以,显然,我不能包括我的母版页布局
好吧,对于你们许多人来说,这个问题可能有一个非常明显的答案,但它让我难住了。 我有一个 asp.net Web 表单,上面有两个控件(嗯,不止这两个,但我们将重点关注这些) - 第一个是 asp:dr
当我将 ASP.NET 复选框控件设置为 asp.net 更新面板的异步回发触发器时,EventName 属性是什么? 最佳答案 我相信它是 CheckedChanged。 关于asp.net - a
我有一个用经典 asp 编写的(巨大的)网站。现在我必须切换到 vb.net (razor)。有没有办法将这两个结合起来直到切换完成? 有没有办法让应用程序与经典的 asp 和 vb.net 一起工作
I am creating a products page, where the user selects an option in a radiobuttonlist for example, an
我最近将一个经典的 ASP 应用程序转换为 ASP.NET 3.5,但我觉得我的经典 ASP 版本要快一些(我不知道可能买家会后悔)。 所以你们能帮我解决这个问题吗,让我知道哪个更快,asp、asp.
从本周开始,我被要求开始学习如何使用 ASP 开发网站。我通过 XNA 对 C# 有一定的经验,所以这部分对我来说并不是什么麻烦。 我一直在关注Music Store Tutorial这需要我设置一个
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我想将一些表单变量发布到经典 ASP 页面中。我不想改变经典的 ASP 页面,因为需要完成大量的工作,以及消耗它们的页面数量。 经典的 ASP 页面需要将表单变量 Username 和 Userpas
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
在某种程度上,这可能是一个异端问题。我们有一个大型站点,其中许多页面仍在ASP中。通常,并没有真正动态的,而是包括(通过SSI或Server.Execute)定期重新生成的HTML块。看起来好像是一个
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我有一个遗留的 ASP 应用程序——在不久的某个时候——需要迁移到 ASP.Net 2.0(以与也在 2.0 中的其他应用程序兼容)。 对于这类事情是否有最佳实践,即作为第一步将当前 html、vbs
我目前在一家公司工作,该公司使用 ASP.NET Webforms 和旧 ASP 页面的组合进行 Web 开发。这对于他们当前的项目来说效果很好,但我想说服/建议他们切换到 ASP.NET MVC,因
我有一个经典的 asp 应用程序。我想将该页面的竞赛表格发布到 Asp.Net 表格。原因是我想在进入数据库之前使用我在 Asp.Net 页面中内置的大量逻辑进行验证,而我对 asp 不太了解。更不用
我知道在 ASP.NET MVC 中,您可以拥有移动 View 并执行类似 Index.mobile.cshtml 的操作。和 _Layout.mobile.cshtml并且服务器知道将这些 View
我需要从一些服务器端 c#.net 代码中调用经典 asp 页面上的 VBscript 函数 - 有谁知道一种干净的方法来做到这一点?在 .net 中重写函数不是一种选择。 我会再解释一下这个问题..
我是一名优秀的程序员,十分优秀!