Reading every incoming request (URL) in ASP.NET WEB API

I used the ASP.NET MVC . In this structure, we checked each incoming request (url) for a certain key and assigned it to a property. We created a custom class that was obtained from the Controller class, and override OnActionExecuting() to provide our custom logic.

How can we achieve the same result in the ASP.NET API?

 //Implementation from ASP.NET MVC public class ApplicationController : Controller { public string UserID { get; set; } protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (!string.IsNullOrEmpty(Request.Params["uid"])) UserID = Request.Params["uid"]; base.OnActionExecuting(filterContext); } } 

What I tried in ASP.NET WEB API:. Although this works, I wonder if this is correct?

Base controller created

 public class BaseApiController : ApiController { public string UserID { get; set; } } 

Created another class that inherits the ActionFilterAttribute class, and I override OnActionExecuting ()

 public class TokenFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) { var queryString = actionContext.Request.RequestUri.Query; var items = HttpUtility.ParseQueryString(queryString); var userId = items["uid"]; ((MyApi.Data.Controllers.BaseApiController)(actionContext.ControllerContext.Controller)).UserID = userId; } } 

Now register this class

 public static void Register(HttpConfiguration config) { config.Filters.Add(new TokenFilterAttribute()); } 
+5
source share
1 answer

You can use message handlers from the ASP.NET web interface. This is a typical security scenario when you need to get some user token from a query string, URL or HTTP header

http://www.asp.net/web-api/overview/advanced/http-message-handlers

1. When you just need to extract the userId from the URL, use it as a parameter for your Api method, and ASP.NET WebAPI will work for you, for example

 [HttpGet, Route("{userId}/roles")] public UserRoles GetUserRoles(string userId, [FromUri] bool isExternalUser = true) 

It works for such a request

 http://.../15222/roles?isExternalUser=false 

2. If this is a security scenario, refer to http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api Basically you need a MessageHandler, or you can also use filter attributes, this is a mechanism in the ASP.NET Web API to intercept every call.

If you need to process each request, then MessageHandler is your way. You need to implement MessageHanler and then register it.

Easy to say, the typical MessageHandler is a class derived from MessageHandler or DelegatingHandler with the SendAsync override method:

 class AuthenticationHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // Your code here return base.SendAsync(request, cancellationToken); } } And you need register it static class WebApiConfig { public static void Register(HttpConfiguration config) { // Other code for WebAPI registerations here config.MessageHandlers.Add(new AuthenticationHandler()); } } 

and name it from Global.asax.cs

WebApiConfig.Register (GlobalConfiguration.Configuration);

An example is the fictitious hypothetical implementation of such a handler (here you need to implement your UidPrincipal from IPrincipal and UidIdentity from IIdentity)

 public class AuthenticationHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { try { var queryString = actionContext.Request.RequestUri.Query; var items = HttpUtility.ParseQueryString(queryString); var userId = items["uid"]; // Here check your UID and maybe some token, just dummy logic if (userId == "D8CD2165-52C0-41E1-937F-054F24266B65") { IPrincipal principal = new UidPrincipal(new UidIdentity(uid), null); // HttpContext exist only when hosting as asp.net web application in IIS or IISExpress if (HttpContext.Current != null) { HttpContext.Current.User = principal; } else { Thread.CurrentPrincipal = principal; } return base.SendAsync(request, cancellationToken); } catch (Exception ex) { this.Log().Warn(ex.ToString()); return this.SendUnauthorizedResponse(ex.Message); } } else { return this.SendUnauthorizedResponse(); } } catch (SecurityTokenValidationException) { return this.SendUnauthorizedResponse(); } } } 

And it allows you to access it from some ASP.NET WebApi method or some property in the WebAPI class

 var uid = ((UidIdentity)User.Identity).Uid 
+7
source

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


All Articles