6

Czy to możliwe w przypadku implementacji Owens Middleware do dodawania roszczeń przed wykonaniem kontrolera Web API?Dodawanie roszczeń z Owin Middleware

Utworzono implementację OwinMiddleware i dodaje tożsamość:

var id = new ClaimsIdentity(); 
id.AddClaim(new Claim("Whatever", "is possible")); 
context.Authentication.User.AddIdentity(id); 

await Next.Invoke(context); 

Jednak nawet nazwać to Invoke metoda tożsamość nie są aktualizowane (tylko tablica roszczenia wewnętrzny). A kontroler po wykonaniu oczywiście nigdy nie otrzyma nowego oświadczenia manekina.

Pomysły?

+1

Po rozmowie z @Pinpoint na holu Owin w JabbR wydaje się, że jedynym sposobem na linii uwierzytelniania jest przez UseOAuthBearerAuthentication w IAppBuilder przez określenie dostawcy niestandardowego. Roszczenia można następnie dodać do kontekstu tożsamości (context.Ticket.Identity.AddClaim (...)). Odbywa się to na żądanie. –

Odpowiedz

1

Może się okazać przydatny dziedziczenie z Authorizate atrybutów i rozszerzenie go do swoich wymagań:

public class DemoAuthorizeAttribute : AuthorizeAttribute 
    {  

     public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext){ 
      if (Authorize(actionContext)){ 
       return; 
      } 
      HandleUnauthorizedRequest(actionContext); 
     } 

     protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext){ 
      var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized; 

//Adding your code here 
var id = new ClaimsIdentity(); 
id.AddClaim(new Claim("Whatever", "is possible")); 
context.Authentication.User.AddIdentity(id); 

      challengeMessage.Headers.Add("WWW-Authenticate", "Basic"); 
      throw new HttpResponseException(challengeMessage); 
     } 

     private bool Authorize(System.Web.Http.Controllers.HttpActionContext actionContext){ 
      try{ 
       var someCode = (from h in actionContext.Request.Headers where h.Key == "demo" select h.Value.First()).FirstOrDefault(); 

       // or check for the claims identity property. 
       return someCode == "myCode"; 
      } 
      catch (Exception){ 
       return false; 
      } 
     } 
    } 

aw kontrolerze:

[DemoAuthorize] 
public class ValuesController : ApiController{ 

Oto link na innej niestandardowej implementacja dla WebAPI upoważnień :

http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/

+0

Jedyny problem, jaki udało mi się znaleźć, dotyczy tego, czy obsługujesz wiele metod autoryzacji, np. OAuth i HMAC musisz wdrożyć wzbogacanie roszczeń w wielu miejscach, stąd moja odpowiedź poniżej. –

0

Jest już klasa, która może dostarczyć roszczeniom wzbogacania ClaimsAuthenticationManager, które można rozszerzyć tak, że obsługuje swoich roszczeń specyficznych domen, na przykład ...

public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager 
{ 
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) 
    { 
     if (!incomingPrincipal.Identity.IsAuthenticated) 
     { 
      return base.Authenticate(resourceName, incomingPrincipal); 
     } 

     return AddApplicationClaims(incomingPrincipal); 
    } 

    private ClaimsPrincipal AddApplicationClaims(ClaimsPrincipal principal) 
    { 
     // TODO: Add custom claims here based on current principal. 

     return principal; 
    } 
} 

Następny zadaniem jest zapewnienie odpowiedniej warstwy pośredniej do powoływania się na to. Dla moich projektów Pisałem następujących klas ...

/// <summary> 
/// Middleware component to apply claims transformation to current context 
/// </summary> 
public class ClaimsTransformationMiddleware 
{ 
    private readonly Func<IDictionary<string, object>, Task> next; 
    private readonly IServiceProvider serviceProvider; 

    public ClaimsTransformationMiddleware(Func<IDictionary<string, object>, Task> next, IServiceProvider serviceProvider) 
    { 
     this.next = next; 
     this.serviceProvider = serviceProvider; 
    } 

    public async Task Invoke(IDictionary<string, object> env) 
    { 
     // Use Katana's OWIN abstractions 
     var context = new OwinContext(env); 

     if (context.Authentication != null && context.Authentication.User != null) 
     { 
      var manager = serviceProvider.GetService<ClaimsAuthenticationManager>(); 
      context.Authentication.User = manager.Authenticate(context.Request.Uri.AbsoluteUri, context.Authentication.User); 
     } 

     await next(env); 
    } 
} 

a następnie rozszerzenie przewodów ...

public static class AppBuilderExtensions 
{ 
    /// <summary> 
    /// Add claims transformation using <see cref="ClaimsTransformationMiddleware" /> any depdendency resolution is done via IoC 
    /// </summary> 
    /// <param name="app"></param> 
    /// <param name="serviceProvider"></param> 
    /// <returns></returns> 
    public static IAppBuilder UseClaimsTransformation(this IAppBuilder app, IServiceProvider serviceProvider) 
    { 
     app.Use<ClaimsTransformationMiddleware>(serviceProvider); 

     return app; 
    } 
} 

wiem, że to jest usługa lokalizatora anty-wzorzec, ale stosując IServiceProvider pojemnik jest neutralny i wydaje się być akceptowanym sposobem umieszczania zależności w oprogramowaniu Owin.

Ostatni trzeba podłączyć ten w swoim starcie, przykład poniżej zakłada jedność i Rejestrowanie/wystawiając nieruchomość IServiceLocator ...

// Owin config 
app.UseClaimsTransformation(UnityConfig.ServiceLocator); 
0

ten sposób skończyło się dodanie nowego roszczenia w owin middleware, na podstawie komentarza OP o zahaczeniu o UseOAuthBearerAuthentication. Używa IdentityServer3.AccessTokenValidation, która wewnętrznie wywołuje UseOAuthBearerAuthentication i przekazuje do niego OAuthBearerAuthenticationProvider.

using System.Security.Claims; 
using System.Threading.Tasks; 
using IdentityServer3.AccessTokenValidation; 
using Owin; 
using Microsoft.Owin.Security.OAuth; 

//... 

public void Configuration(IAppBuilder app) 
{ 
    app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions 
    { 
     Authority = "http://127.0.0.1/identityserver", 
     TokenProvider = new OAuthBearerAuthenticationProvider 
     { 
      OnValidateIdentity = AddClaim 
     } 
    }); 
} 

private Task AddClaim(OAuthValidateIdentityContext context) 
{ 
    context.Ticket.Identity.AddClaim(new Claim("test", "123")); 
    return Task.CompletedTask; 
} 
Powiązane problemy