C# Windows身份验证-特殊用户需要额外密码
我正在开发一个内部网asp.net核心web api应用程序。认证要求如下:C# Windows身份验证-特殊用户需要额外密码,c#,asp.net-core,windows-authentication,C#,Asp.net Core,Windows Authentication,我正在开发一个内部网asp.net核心web api应用程序。认证要求如下: REQ1-当试图访问网站的用户不在Active Directory的特殊组(让我们将其命名为“commonUsers”)中时,它就是没有授权的 REQ2-当试图访问网站的用户在Active Directory的组中时,“commonUsers”被授权并返回web资源 REQ3-当试图访问网站的用户位于Active Directory的组“超级用户”中时,需要再次提示其输入域密码(因为它试图访问一些非常受限的资源)
- REQ1-当试图访问网站的用户不在Active Directory的特殊组(让我们将其命名为“commonUsers”)中时,它就是没有授权的
- REQ2-当试图访问网站的用户在Active Directory的组中时,“commonUsers”被授权并返回web资源
- REQ3-当试图访问网站的用户位于Active Directory的组“超级用户”中时,需要再次提示其输入域密码(因为它试图访问一些非常受限的资源)
- 我的服务使用http.sys服务器托管,以支持windows身份验证李>
- 我使用声明是为了检查用户的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); }}
public类claimtransformer:iclaims转换{ 私有只读IAuthorizationService\u授权服务; 公开请求传输格式(IAAuthorizationService授权服务) { _授权服务=授权服务; } 公共任务TransformAsync(ClaimsPrincipal主体) { _授权服务。授权(委托人作为IHMICLAIMS委托人); 返回任务.FromResult(主体); }}
- 我在服务配置中也指定了特殊策略,例如: services.AddAuthorization(options => { options.AddPolicy("TestPolicy", policy => policy.RequireClaim(ClaimTypes.Role, "TestUser")); options.AddPolicy("TestPolicy2", policy => policy.RequireClaim(ClaimTypes.Role, "SuperUser")); }); services.AddAuthorization(选项=> { options.AddPolicy(“TestPolicy”,policy=> policy.requirecall(ClaimTypes.Role,“TestUser”); options.AddPolicy(“TestPolicy2”,policy=> policy.requirecall(ClaimTypes.Role,“超级用户”); });李>
- 我正在使用带有特定策略的
属性,以便根据策略限制对特定资源的访问[Authorize]
现在的问题是,我应该如何满足REQ3?我猜您正在尝试对
部分资源实施两步身份验证
为此,您必须使用多个身份验证方案
和授权策略
,
但这很困难,因为windows身份验证是不可控的。我们需要使用一些技巧来知道这是你的第二次登录
认证
默认的身份验证方案:Windows
,它是对Windows用户进行身份验证的基本方案
第二个Cookies
基本身份验证方案:SuperUserTwoStep
。我们需要这个来转到我们的自定义登录逻辑
授权
指定方案的授权策略
用于登录到SuperUserTwoStep
方案的登录页面
<>最困难的事情是跟踪这是第二次登录,我尝试使用Cookie,但是它不工作,所以我装箱一个<代码>静态的自动机< /代码>跟踪,<强>也许使用分布式缓存更好的< /强> < p>我认为你应该考虑使用:基于策略的授权与需求,基本上,您有不同的授权要求,希望根据这些要求进行处理
需求1、需求2和需求3
这里有指向文档的链接:
但你需要了解这种身份权限,那些向微软介绍策略概念的人创建了一个名为:PolicyServer的项目,它是开源的:他们在那里创建了一个你应该如何使用策略的模式。基本上,您的外部和内部用户都是根据您的广告进行身份验证的,所有内部用户都应该具有分配给角色的权限。并且您只使用为该策略创建的权限规则来修饰控制器操作
[Authorize("PerformSurgery")]
public async Task<IActionResult> PerformSurgery()
{
// omitted
}
[授权(“执行外科手术”)]
公共异步任务PerformSurgery()
{
//省略
}
为了理解代码以及他们如何评估策略,我认为您应该查看他们在网站上的在线视频:
希望这有帮助我想我会尝试使用MVC过滤器:
过滤器在所有中间件之后但在操作之前运行。这将允许您仅为特定操作或控制器控制重定向到凭据页面。虽然通常这不是推荐的授权方法,但我认为它符合您对混合二级身份验证的要求
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);
}
}
然后,您可以根据需要装饰特定操作(或控制器):
public class MyController : Controller
{
[HttpGet]
[SuperUserFilter]
public IActionResult MySensitiveAction()
{
// Do something sensitive
}
}
如果您的web应用程序故意返回401响应,浏览器应该提示。IE也是这样吗?嗯,您没有尝试吗?@niao您是否尝试对超级用户实施两步身份验证?@John-这似乎是我尝试使用Windows身份验证来做的。我会检查这一点。这似乎有效,但是,当我想要访问特定的资源时,例如超级用户可以访问的/api/TestController/SomeAction,应该再次提示输入凭据(在这种情况下,PUT和GET操作是可禁用的)和其他类型的用户(不应该再次提示输入凭据),会出现什么情况-在这种情况下,只读资源可用(获取操作)?@niao在这种情况下,您可以定义一个和一个处理程序来自己处理authorze策略。PS:也可以尝试使用<代码> XHR <代码>访问“两步”API,不确定它是否会显示凭据弹出窗口。@ NIAO还考虑了<代码> @ StfU/<代码>的建议,使用其他验证方法来确认两步授权(例如使用SMS或电子邮件发送的确认代码,甚至显示在屏幕上),windows登录太难控制了我会检查的
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);
}
}
public class MyController : Controller
{
[HttpGet]
[SuperUserFilter]
public IActionResult MySensitiveAction()
{
// Do something sensitive
}
}