ASP.NET Web API 2 -> Windows 身份验证 -> 在 Azure 上模拟 Windows 用户
ASP.NET Web API 2 -> Windows Authentication -> Impersonate Windows user on Azure
我们正在使用 Windows Authentication
开发一个在公司内部使用的应用程序。我们查看了 ADFS
但目前这不是一个选项。问题是我们的测试服务器完全是基于 Azure
的云。一直在寻找激活用户的方法,一直没有找到好的解决办法
我的第一个想法是完全关闭 authentication
。这很好用,但我们有一些资源可以检查用户角色,所以我不得不放弃这个想法。
<system.web>
<authentication mode="None" />
</system.web>
returns 401 Unauthorized
和 authentication mode="None"
的示例方法,显然:
[Authorize(Roles = "Administrator")]
[HttpGet]
[Route("TestMethod")]
public IHttpActionResult TestMethod()
{
return Ok("It works!");
}
我的第二个想法是编辑 WebApiConfig
并尝试在每个请求服务器端添加身份验证 headers。然而,当我开始查看 NTLM Authentication Scheme for HTTP
和 4 次握手时,我意识到这可能是不可能的。
NTLM Authentication Scheme for HTTP
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Other code for WebAPI registerations here
config.MessageHandlers.Add(new AuthenticationHandler());
}
}
class AuthenticationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Add authentication to every request...
return base.SendAsync(request, cancellationToken);
}
}
因为没有 Owin (Katana)
我不能编辑标准 App_Start -> Startup.Auth.cs -> public void ConfigureAuth(IAppBuilder app)
并在那里尝试一些东西。无论如何,我不知道如何构建 "user object"。
我们对此有什么办法吗?还是我们必须在本地测试所有内容?如果我们可以模拟一个用户为每个请求登录,这在测试环境中就没问题了。
就伪造身份验证和授权而言,您应该能够使用 FilterAttribute 设置具有适当角色的通用用户主体。
public class TestIdentityFilter : FilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
filterContext.Principal = new GenericPrincipal(
new GenericIdentity(),
new string [] {"Administrator"});
}
}
您需要像之前那样设置 <authentication mode="None" />
否则此代码将永远不会在您的测试环境中命中。
将其添加为全局过滤器将覆盖任何其他现有的身份验证系统(例如,如果您错误地将其部署到经过身份验证的环境中)。显然,您需要非常小心地只在您的测试系统中使用它。
此示例基于 MVC,我认为与 WebApi 有一些非常小的差异,但基本原则适用。
非常感谢@ste-fu 为我指明了正确的方向。完整代码:
public class AppSettingsDynamicRolesAuthorizeAttribute : AuthorizeAttribute
{
public AppSettingsDynamicRolesAuthorizeAttribute(params string[] roleKeys)
{
List<string> roles = new List<string>(roleKeys.Length);
foreach (var roleKey in roleKeys)
{
roles.Add(WebConfigurationManager.AppSettings[roleKey]);
}
this.Roles = string.Join(",", roles);
}
public override void OnAuthorization(HttpActionContext filterContext)
{
if (Convert.ToBoolean(WebConfigurationManager.AppSettings["IsTestEnvironment"]))
{
filterContext.RequestContext.Principal = new GenericPrincipal(
new GenericIdentity("Spoofed-Oscar"),
new string[] { WebConfigurationManager.AppSettings[Role.Administrator] });
}
base.OnAuthorization(filterContext);
}
}
public static class Role
{
public const string Administrator = "Administrator";
public const string OtherRole = "OtherRole";
}
然后可以这样使用:
[AppSettingsDynamicRolesAuthorize(Role.Administrator, Role.OtherRole)]
[HttpGet]
[Route("Test")]
public IHttpActionResult Get()
{
var userName = RequestContext.Principal.Identity.Name;
var user = HttpContext.Current.User.Identity;
return Ok("It works!");
}
我们正在使用 Windows Authentication
开发一个在公司内部使用的应用程序。我们查看了 ADFS
但目前这不是一个选项。问题是我们的测试服务器完全是基于 Azure
的云。一直在寻找激活用户的方法,一直没有找到好的解决办法
我的第一个想法是完全关闭 authentication
。这很好用,但我们有一些资源可以检查用户角色,所以我不得不放弃这个想法。
<system.web>
<authentication mode="None" />
</system.web>
returns 401 Unauthorized
和 authentication mode="None"
的示例方法,显然:
[Authorize(Roles = "Administrator")]
[HttpGet]
[Route("TestMethod")]
public IHttpActionResult TestMethod()
{
return Ok("It works!");
}
我的第二个想法是编辑 WebApiConfig
并尝试在每个请求服务器端添加身份验证 headers。然而,当我开始查看 NTLM Authentication Scheme for HTTP
和 4 次握手时,我意识到这可能是不可能的。
NTLM Authentication Scheme for HTTP
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Other code for WebAPI registerations here
config.MessageHandlers.Add(new AuthenticationHandler());
}
}
class AuthenticationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Add authentication to every request...
return base.SendAsync(request, cancellationToken);
}
}
因为没有 Owin (Katana)
我不能编辑标准 App_Start -> Startup.Auth.cs -> public void ConfigureAuth(IAppBuilder app)
并在那里尝试一些东西。无论如何,我不知道如何构建 "user object"。
我们对此有什么办法吗?还是我们必须在本地测试所有内容?如果我们可以模拟一个用户为每个请求登录,这在测试环境中就没问题了。
就伪造身份验证和授权而言,您应该能够使用 FilterAttribute 设置具有适当角色的通用用户主体。
public class TestIdentityFilter : FilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
filterContext.Principal = new GenericPrincipal(
new GenericIdentity(),
new string [] {"Administrator"});
}
}
您需要像之前那样设置 <authentication mode="None" />
否则此代码将永远不会在您的测试环境中命中。
将其添加为全局过滤器将覆盖任何其他现有的身份验证系统(例如,如果您错误地将其部署到经过身份验证的环境中)。显然,您需要非常小心地只在您的测试系统中使用它。
此示例基于 MVC,我认为与 WebApi 有一些非常小的差异,但基本原则适用。
非常感谢@ste-fu 为我指明了正确的方向。完整代码:
public class AppSettingsDynamicRolesAuthorizeAttribute : AuthorizeAttribute
{
public AppSettingsDynamicRolesAuthorizeAttribute(params string[] roleKeys)
{
List<string> roles = new List<string>(roleKeys.Length);
foreach (var roleKey in roleKeys)
{
roles.Add(WebConfigurationManager.AppSettings[roleKey]);
}
this.Roles = string.Join(",", roles);
}
public override void OnAuthorization(HttpActionContext filterContext)
{
if (Convert.ToBoolean(WebConfigurationManager.AppSettings["IsTestEnvironment"]))
{
filterContext.RequestContext.Principal = new GenericPrincipal(
new GenericIdentity("Spoofed-Oscar"),
new string[] { WebConfigurationManager.AppSettings[Role.Administrator] });
}
base.OnAuthorization(filterContext);
}
}
public static class Role
{
public const string Administrator = "Administrator";
public const string OtherRole = "OtherRole";
}
然后可以这样使用:
[AppSettingsDynamicRolesAuthorize(Role.Administrator, Role.OtherRole)]
[HttpGet]
[Route("Test")]
public IHttpActionResult Get()
{
var userName = RequestContext.Principal.Identity.Name;
var user = HttpContext.Current.User.Identity;
return Ok("It works!");
}