C# 使用OWIN自托管WebApi声明身份验证

C# 使用OWIN自托管WebApi声明身份验证,c#,authentication,asp.net-web-api,owin,claims-based-identity,C#,Authentication,Asp.net Web Api,Owin,Claims Based Identity,我使用以下配置自托管WebApi: Visual Studio 2012/.NET 4.0 public void Configuration(IAppBuilder appBuilder) { var config = new HttpConfiguration(); // authentication config.MessageHandlers.Add(new Shield.PresharedKeyAuthorizer()); // routing

我使用以下配置自托管WebApi:

Visual Studio 2012/.NET 4.0

public void Configuration(IAppBuilder appBuilder)
{
    var config = new HttpConfiguration();

    // authentication
    config.MessageHandlers.Add(new Shield.PresharedKeyAuthorizer());

    // routing
    config.Routes.MapHttpRoute(
        name: "Default",
        routeTemplate: "{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    appBuilder.UseWebApi(config);
}
我有一个简单的测试设置,使用以下
DelegatingHandler
创建声明并将其附加到当前线程

public class PresharedKeyAuthorizer : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.Name, "superstar"));

        var identity = new ClaimsIdentity(claims, "PresharedKey");
        var principal = new ClaimsPrincipal(identity);

        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
            HttpContext.Current.User = principal;

        return base.SendAsync(request, cancellationToken);
    }
}
删除
Authorize
属性并设置断点,我可以看到RequestContext.Principal属性确实为null。请求在没有
Authorize
属性的情况下工作,因此我知道自托管的设置是正确的,但我必须在身份验证管道中缺少一些内容

允许该声明对
Authorize
属性起作用,我遗漏了什么


当由IIS托管时,此具有相同方法的相关答案似乎有效:

在消息处理程序中,按如下方式设置主体

request.GetRequestContext().Principal = principal;
不要使用

Thread.CurrentPrincipal = principal;

if (HttpContext.Current != null)
    HttpContext.Current.User = principal;
更新

我已经有一段时间没有使用.NET4.0/2012/WebAPI了 { var索赔=新列表(); 索赔。添加(新索赔(ClaimTypes.Name,“superstar”); var标识=新的索赔实体(索赔,“预共享密钥”); var principal=新的ClaimsPrincipal(身份); context.Request.User=主体; 返回next.Invoke(); }); app.UseWebApi(配置); }
这是否仅在WebApi 2.0中可用?我正在运行.Net4.0/VS2012,我将把它添加到我的答案中。是的,但是您不是已经在使用web API 2了吗?我以为你正在检查
HttpRequestContext
上的
Principal
。你说得对,我使用的是webapi2。实际上,我正在控制器上使用authorized属性,它应该检查我相信的当前线程主体。
[Authorize]
获取如下主体-
IPrincipal user=actionContext.ControllerContext.RequestContext.principal。谢谢。您的第一个答案现在可以正常工作了。我花了一些时间才意识到来自WebApi的
[Authorize]
属性与来自System.Web的
[Authorize]
具有不同的实现。我只需要引用正确的一个。对于可移植性,我将设置所有三个值,使其无论在何处托管都能工作。
Thread.CurrentPrincipal = principal;

if (HttpContext.Current != null)
    HttpContext.Current.User = principal;
public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute("default", "api/{controller}/{id}");

    //config.MessageHandlers.Add(new PresharedKeyAuthorizer());

    app.Use((IOwinContext context, Func<Task> next) =>
    {
        var claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.Name, "superstar"));

        var identity = new ClaimsIdentity(claims, "PresharedKey");
        var principal = new ClaimsPrincipal(identity);

        context.Request.User = principal;
        return next.Invoke();
    });

    app.UseWebApi(config);
}