Adding claims with Owin middleware

Is it possible to add claims with the implementation of Owin Middleware before executing the web API controller?

Created an OwinMiddleware implementation and added an identifier:

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

However, even this Call method invokes identities that are not updated (only an array of internal statements). And the controller, when executed, of course, never gets a new dummy statement.

Ideas?

+6
source share
3 answers

You can find useful inheritance from the Authorizate attribute and extend it to fit your requirements:

 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; } } } 

And in your controller:

 [DemoAuthorize] public class ValuesController : ApiController{ 

Here is a link to another custom implementation for authorizing WebApi:

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

+1
source

There is already a class that can provide ClaimsAuthenticationManager claims correction, which you can extend to handle your domain-related requests, for example ...

 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; } } 

The next task is to provide the appropriate middleware to call this. For my projects, I wrote the following classes ...

 /// <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 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); } } 

And then expand the wiring ...

 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; } } 

I know this is an anti-pattern for a service locator, but using IServiceProvider is a neutral container and seems to be an acceptable way to place dependencies in Owin middleware.

The last thing you need to associate with this at startup, the example below assumes Unity and registers / expands the IServiceLocator property ...

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

Here's how I ended up adding a new requirement to owin middleware based on OP's comment on connecting to UseOAuthBearerAuthentication. It uses IdentityServer3.AccessTokenValidation, which calls the UseOAuthBearerAuthentication function internally and passes the OAuthBearerAuthenticationProvider through it.

 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; } 
0
source

Source: https://habr.com/ru/post/982047/


All Articles