2014-09-02 13 views
5

Użyłem ramy ASP.NET MVC. W tym kontekście sprawdziliśmy każde przychodzące żądanie (adres URL) pod kątem jakiegoś klucza i przypisaliśmy go do właściwości. Stworzyliśmy niestandardową klasę, która wywodzi się z Controller klasy &, , zastępującOnActionExecuting(), aby zapewnić naszą niestandardową logikę.Czytanie każdego przychodzącego żądania (adresu URL) w ASP.NET WEB API

Jak możemy osiągnąć to samo w ASP.NET WEB 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); 
    }  
} 

Co Próbowałem w ASP.NET Web API: - Choć to działa, zastanawiam się, czy to jest prawidłowe podejście?

Utworzono podstawowy kontroler

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

stworzyła kolejną klasę, która dziedziczy ActionFilterAttribute klasę & zastąpić 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; 


      } 
    } 

teraz zarejestrować tej klasy

public static void Register(HttpConfiguration config) 
{ 
    config.Filters.Add(new TokenFilterAttribute()); 
} 

Odpowiedz

7

Można używać programów do obsługi komunikatów z interfejsu ASP.NET Web API. Jest to typowy scenation bezpieczeństwo, kiedy trzeba się trochę obsługi tokenu z łańcucha zapytania, URL lub HTTP Header

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

1.W przypadku, gdy trzeba po prostu wyodrębnić identyfikatora użytkownika z adresem URL, a następnie użyć go jako parametr metoda Api i ASP.NET WebAPI zrobi za Ciebie, jak

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

pracować dla takiego wniosku

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

2.Jeżeli to s Scenariusz urity, proszę odnieść się do http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api Zasadniczo będziesz potrzebować niektórych MessageHandler lub możesz użyć atrybutów filtru, jak również mechanizm ASP.NET Web API przechwytuje każde wywołanie.

Jeśli potrzebujesz przetworzyć każde żądanie, to MessageHandler jest na twojej drodze. Musisz zaimplementować MessageHanler, a następnie go zarejestrować.

Stwierdzenie, łatwo typowy MessageHandler klasa pochodzące z MessageHandler lub DelegatingHandler metodą SendAsync nadpisane:

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

i wywołania z Global.asax.cs

WebApiConfig.Register (GlobalConfiguration.Konfiguracja);

Niektóre przykład obojętne hipotetyczna realizacja takiego programu obsługi (tutaj trzeba imeplement swoją UidPrincipal z IPrincipal i UidIdentity z 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(); 
     } 
    } 
} 

i umożliwia dostęp do niego z pewnym sposobem ASP.NET WebAPI lub jakiejś nieruchomości w WebAPI klasa

var uid = ((UidIdentity)User.Identity).Uid 
+0

Dziękujemy za szybką pomoc. Przed opublikowaniem pytania sprawdzałem ten adres URL i nie wiem, w jaki sposób to pomoże w moim przypadku. Czy możesz podać mi więcej szczegółów. – SharpCoder

+0

Próbowałem dodać trochę kodu i uczynić go bardziej zrozumiałym. Jaki jest twój przypadek użycia? Dlaczego potrzebujesz wyodrębnić identyfikator użytkownika z każdego żądania? – Regfor

+0

Niektóre z żądań będą miały wartość 'userId' przekazywaną jako ciąg zapytania. Chcę tylko sprawdzić każde żądanie i jeśli ciąg zapytania ma wartość 'userId', odczytam go i przypisze do właściwości' UserID' w 'BaseController'. 'BaseController' będzie dziedziczyć po' ApiController'. I wszystkie moje kontrolery odziedziczą po 'BaseController'. Który zapewni właściwość 'UserID' jest dostępna dla wszystkich kontrolerów. Problem polega na tym, że "DelegatingHandler" jest także klasą, w przeciwieństwie do interfejsu 'IActionFilter' który jest dostępny w ASP.NET MVC – SharpCoder