我正在开发一个intranet asp.net核心Web api应用程序。身份验证的要求是:
现在,我到目前为止所拥有的:
我正在使用Claims Middleer来检查用户的Active Directory组,让我们这样说:
public class ClaimsTransformer : IClaimsTransformation {
private readonly IAuthorizationService _authorizationService;
public ClaimsTransformer(IAuthorizationService authorizationService)
{
_authorizationService = authorizationService;
}
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
_authorizationService.Authorize(principal as IHmiClaimsPrincipal);
return Task.FromResult(principal);
}}
我还在服务配置中指定了特殊策略,例如:
services.AddAuthorization(options => { options.AddPolicy("TestPolicy", policy => policy.RequireClaim(ClaimTypes.Role, "TestUser")); options.AddPolicy("TestPolicy2", policy => policy.RequireClaim(ClaimTypes.Role, "SuperUser")); });
我正在将[Authorize]
属性与特定策略结合使用,以便根据策略限制对特定资源的访问
现在的问题是,我应该如何满足REQ3?
答案 0 :(得分:2)
我想我会尝试使用MVC过滤器:https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2#authorization-filters
过滤器在所有中间件之后运行,但在操作之前运行。这将允许您仅针对特定操作或控制器来控制“重定向到凭据”页面。通常,这不是推荐的授权方法,但我认为这符合您对混合二级身份验证的要求。
RefId
然后您创建一个登录控制器
public class SuperUserFilter : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
if (context.HttpContext.Request.Cookies.TryGetValue("SuperUserCookie", out string cookieVal))
{
if (!IsValidCookie(cookieVal))
context.Result = LoginPage(context);
}
else
{
context.Result = LoginPage(context);
}
}
private bool IsValidCookie(string cookieVal)
{
//validate cookie value somehow
// crytpographic hash, store value in session, whatever
return true;
}
private ActionResult LoginPage(AuthorizationFilterContext context)
{
return new RedirectToActionResult("SuperUser", "Login",
new {redirectUrl = context.HttpContext.Request.GetEncodedUrl()});
}
}
然后,您可以根据需要装饰特定的操作(或控制器):
public class LoginController : Controller
{
[HttpGet]
public IActionResult SuperUser(string redirectUrl)
{
// return a page to enter credentials
// Include redirectUrl as field
}
[HttpPost]
public IActionResult SuperUser(LoginData loginData)
{
// Validate User & Password
Response.Cookies.Append("SuperUserCookie", "SomeValue");
return Redirect(loginData.RedirectUrl);
}
}
答案 1 :(得分:0)
我猜您正在尝试为some of your resource
实施两步身份验证。
为此,您必须使用多个authentication scheme
和Authorize policies
,
但是这很困难,因为Windows身份验证是不可控制的。我们需要使用一些技巧才能知道这是您的第二次登录。
Windows
,它是用于验证Windows用户的基本方案。Cookies
的认证方案:SuperUserTwoStep
。我们需要使用它来进入我们的自定义登录逻辑。Authorize policies
。SuperUserTwoStep
方案的登录页面。//startup
services.AddAuthentication(HttpSysDefaults.AuthenticationScheme)
.AddCookie("SuperUserTwoStep",op=>op.LoginPath = "/account/superuser2steplogin");
services.AddAuthorization(op =>
{
op.AddPolicy("SuperUser", b => b.AddAuthenticationSchemes("SuperUserTwoStep")
.RequireAuthenticatedUser()
.RequireClaim(ClaimTypes.Role, "SuperUser"));
});
// login
public static IDictionary<string, string> States { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
[Route("/account/superuser2steplogin")]
public async Task<IActionResult> LoginTwoStepConfirm(string returnUrl, [FromServices]IAuthorizationService authorizationService,
[FromServices]IAuthorizationPolicyProvider policyProvider)
{
var winresult = await HttpContext.AuthenticateAsync(IISDefaults.AuthenticationScheme);
if (winresult.Succeeded)
{
if (States.TryGetValue(winresult.Principal.Identity.Name, out _))
{
States.Remove(winresult.Principal.Identity.Name);
var principal = new System.Security.Claims.ClaimsPrincipal(new System.Security.Claims.ClaimsIdentity(winresult.Principal.Claims,"twostepcookie"));
await HttpContext.SignInAsync("SuperUserTwoStep", principal);
return Redirect(returnUrl);
}
else
{
States[winresult.Principal.Identity.Name] = "1";
return Challenge(IISDefaults.AuthenticationScheme);
}
}
else
{
return Challenge(IISDefaults.AuthenticationScheme);
}
}
[Authorize("SuperUser")]
public IActionResult YourSecurePage()
{
return Content("hello world");
}
最困难的事情是跟踪这是第二次登录,我尝试使用cookie,但是它不起作用,因此我创建了static IDitionary<string,string>
进行跟踪,也许使用分布式缓存更好
答案 2 :(得分:0)
我认为您应该考虑使用:带需求的基于策略的授权,基本上,您有不同的授权需求,您希望基于AND对其进行处理
REQ1和REQ2和REQ3
在这里您具有文档链接:Requirements
但是您需要了解identity!=权限,向Microsoft引入了这种策略概念的人们创建了一个名为:PolicyServer的项目,该项目是开源的:PolicyServer Git,他们在那里创建了一个模式,您应该如何使用使用您的政策。基本上,您具有根据AD进行身份验证的外部和内部用户,所有内部用户应具有分配给角色的权限。而且,您只会使用为该策略创建的权限规则来装饰控制器操作
[Authorize("PerformSurgery")]
public async Task<IActionResult> PerformSurgery()
{
// omitted
}
要了解代码及其对政策的评估方式,我认为您应该在网站Policy Server
上观看他们在线观看的视频。希望这会有所帮助