C# 使用OWIN自托管WebApi声明身份验证
我使用以下配置自托管WebApi: Visual Studio 2012/.NET 4.0C# 使用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
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);
}