繁体   English   中英

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>

返回带有authentication mode="None" 401 Unauthorized示例方法,显然是:

[Authorize(Roles = "Administrator")]
[HttpGet]
[Route("TestMethod")]
public IHttpActionResult TestMethod()
{
    return Ok("It works!");
}

我的第二个想法是编辑WebApiConfig并尝试在每个请求服务器端添加身份验证标头。 但是,当我开始查看NTLM Authentication Scheme for HTTP和4向握手的NTLM Authentication Scheme for HTTP我意识到这可能是不可能的。

HTTP的NTLM身份验证方案

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)然后在此处尝试某些操作。 无论如何,我不知道如何构建“用户对象”。

我们对此可以采取任何措施还是必须在本地进行所有测试? 如果我们可以模拟一个用户来登录每个请求,那么在测试环境中就可以了。

在伪造认证和授权方面,您应该能够使用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!");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM