12

Я самостоятельно хостинг WebAPI со следующей конфигурацией:Иска Auth с Owin самодостаточно 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); 
    } 
} 

Однако, когда я попал в ApiController, помеченный атрибутом Authorize, он не распознает аутентификацию.

[Authorize] 
public class FilesController : ApiController 
{ 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "Secure File A", "Secure File B" }; 
    } 
} 

Удаление атрибута Authorize и установки точки останова, я могу видеть, что RequestContext.Principal свойство действительно нуль. Запрос работает без атрибута Authorize, поэтому я знаю, что настройка собственного хостинга верна, но я должен что-то пропускать в конвейере аутентификации.

Что мне не хватает, чтобы разрешить эту претензию работать с атрибутом Authorize?

Это родственный ответ с таким же подходом, как представляется, работать при размещении на IIS: https://stackoverflow.com/a/14872968/118224

ответ

17

В обработчике сообщений установи принципал, как это.

request.GetRequestContext().Principal = principal; 

Не используйте

Thread.CurrentPrincipal = principal; 

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

UPDATE

Это было некоторое время, так как я работал на .NET 4.0/2012/Web API < 2. Таким образом, я не могу ответить на конечно. Но с хостингом OWIN, основной должен быть установлен в контексте OWIN. OwinHttpRequestContext устанавливает как Thread.CurrentPrincipal, так и директора в контексте OWIN. Используя request.GetRequestContext().Principal, эти данные скрыты от вас. Короче говоря, я считаю, что если вы каким-то образом зададите принципала в контексте OWIN, это сработает. Не знаете, как это сделать из обработчика сообщений веб-API. Вы можете сделать это из промежуточного программного обеспечения OWIN.

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); 
} 
+0

Доступно ли это только в WebApi 2.0? Я запускаю .Net4.0/VS2012, который я добавлю к своему ответу. –

+0

Да, но разве вы уже не используете веб-API 2? Я думал, что вы проверяете 'Principal' на' HttpRequestContext'. – Badri

+0

Правильно, я использую webapi2. Я на самом деле использую AuthorizeAttribute на контроллере, который должен проверять Текущий поток. –

Смежные вопросы