2015-10-29 9 views
9
  1. ben WebAPI erişimi kısıtlamak isteyen api.example2.com

üzerinde www.example1.com Farklı etki alanlarında MVC öneki ve Web Api arasında Sahtekarlık Önleme Jetonunu nasıl uygularım?

  • WebAPI proje üzerinde MVC proje yapmak istiyorum. Sahteciliğe Karşı Jetonu:

    Uygulamayı denedim Anti-öfke belirteci ile WebApi'ye GET isteği oluşturduğumda, istek bu belirteç içermediğinden bir istisna aldım.

    ValidateRequestHeader adlı yöntemde cookie = null değişkeni değişkendir.

    Aşağıdaki kodları nasıl düzeltebilirim? Bu doğru çözüm mü?

    (ön uç)

    MVC projesi - geliştirme için localhost:33635 geçerli:

    Index.cshtml

    <div class="container"> 
    
    
        <div class="row"> 
    
         <div class="col-md-12"> 
    
    
          <input id="get-request-button" type="button" class="btn btn-info" value="Create request to API Server" /> 
    
          <br /> 
    
          <div id="result"></div> 
    
         </div> 
    
    
        </div> 
    
    
    </div> 
    
    
    @section scripts 
    { 
    
        <script type="text/javascript"> 
    
         @functions{ 
          public string TokenHeaderValue() 
          { 
           string cookieToken, formToken; 
           AntiForgery.GetTokens(null, out cookieToken, out formToken); 
           return cookieToken + ":" + formToken; 
          } 
         } 
    
         $(function() { 
    
          $("#get-request-button").click(function() { 
    
           $.ajax("http://localhost:33887/api/values", { 
            type: "GET", 
            contentType: "application/json", 
            data: {}, 
            dataType: "json", 
            headers: { 
             'RequestVerificationToken': '@TokenHeaderValue()' 
            } 
           }).done(function (data) { 
            $("#result").html(data); 
           }); 
    
           return false; 
          }); 
    
         }); 
    
    
        </script> 
    
    } 
    

    WebAPI projesi - gelişmedir için localhost:33887:

    WebApiConfig.cs

    public static void Register(HttpConfiguration config) 
         { 
          // Web API configuration and services 
    
          config.EnableCors(new EnableCorsAttribute("http://localhost:33635", "*", "*")); 
    
          // Web API routes 
          config.MapHttpAttributeRoutes(); 
    
          config.Routes.MapHttpRoute(
            name: "DefaultApi", 
            routeTemplate: "api/{controller}/{id}", 
            defaults: new { id = RouteParameter.Optional } 
          ); 
         } 
    

    ValidateHttpAntiForgeryTokenAttribute.cs:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] 
        public sealed class ValidateHttpAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 
        { 
         public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) 
         { 
          var request = actionContext.Request; 
    
          try 
          { 
           if (IsAjaxRequest(request)) 
           { 
            ValidateRequestHeader(request); 
           } 
           else 
           { 
            AntiForgery.Validate(); 
           } 
          } 
          catch (Exception) 
          { 
           actionContext.Response = new HttpResponseMessage 
           { 
            StatusCode = HttpStatusCode.Forbidden, 
            RequestMessage = actionContext.ControllerContext.Request 
           }; 
           return FromResult(actionContext.Response); 
          } 
          return continuation(); 
         } 
    
         private Task<HttpResponseMessage> FromResult(HttpResponseMessage result) 
         { 
          var source = new TaskCompletionSource<HttpResponseMessage>(); 
          source.SetResult(result); 
          return source.Task; 
         } 
    
         private bool IsAjaxRequest(HttpRequestMessage request) 
         { 
          IEnumerable<string> xRequestedWithHeaders; 
          if (!request.Headers.TryGetValues("X-Requested-With", out xRequestedWithHeaders)) return false; 
    
          var headerValue = xRequestedWithHeaders.FirstOrDefault(); 
    
          return !String.IsNullOrEmpty(headerValue) && String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase); 
         } 
    
         private void ValidateRequestHeader(HttpRequestMessage request) 
         { 
          var headers = request.Headers; 
          var cookie = headers 
            .GetCookies() 
            .Select(c => c[AntiForgeryConfig.CookieName]) 
            .FirstOrDefault(); 
    
          IEnumerable<string> xXsrfHeaders; 
    
          if (headers.TryGetValues("RequestVerificationToken", out xXsrfHeaders)) 
          { 
           var rvt = xXsrfHeaders.FirstOrDefault(); 
    
           if (cookie == null) 
           { 
            throw new InvalidOperationException($"Missing {AntiForgeryConfig.CookieName} cookie"); 
           } 
    
           AntiForgery.Validate(cookie.Value, rvt); 
          } 
          else 
          { 
           var headerBuilder = new StringBuilder(); 
    
           headerBuilder.AppendLine("Missing X-XSRF-Token HTTP header:"); 
    
           foreach (var header in headers) 
           { 
            headerBuilder.AppendFormat("- [{0}] = {1}", header.Key, header.Value); 
            headerBuilder.AppendLine(); 
           } 
    
           throw new InvalidOperationException(headerBuilder.ToString()); 
          } 
         } 
        } 
    

    ValuesController:

    public class ValuesController : ApiController 
        { 
         // GET: api/Values 
         [ValidateHttpAntiForgeryToken] 
         public IEnumerable<string> Get() 
         { 
          return new string[] { "value1", "value2" }; 
         } 
    
         // GET: api/Values/5 
         public string Get(int id) 
         { 
          return "value"; 
         } 
    
         // POST: api/Values 
         public void Post([FromBody]string value) 
         { 
         } 
    
         // PUT: api/Values/5 
         public void Put(int id, [FromBody]string value) 
         { 
         } 
    
         // DELETE: api/Values/5 
         public void Delete(int id) 
         { 
         } 
        } 
    
  • +0

    @teovankot İki sunucu arasında AntiForgeryToken paylaşımını çözmek istiyorum. Bağlantınız bir sunucuda yalnızca Sahtekarlık Önleyici Jetonu çözüldü. – Jenan

    +0

    Üzgünüm, benim hatam –

    cevap

    6

    Bu başka bir hizmet tarafından erişimi kısıtlamak için bir yol değildir. ForgeryToken, CSRF saldırılarını önlemeye yardımcı olur; ASP.NET MVC, istek doğrulama belirteçleri olarak da adlandırılan, sahtekarlık önleyici jetonlar kullanır. İstemci, bir form içeren bir HTML sayfası ister. Sunucu, yanıtta iki belirteç içerir. Bir jeton çerez olarak gönderilir. Formu gönderdiğinizde, bunlar aynı sunucuda eşleşecektir.

    neye ihtiyacınız olduğunu example1.com'dan api.example2.com'a olan güvendir. An example, Stack Exchange network'un tamamında merkezi hizmetler için bir etki alanı olan stackauth olur. Ardından, projenizde ihtiyacınız olan yetkiyi uygulayabilirsiniz.

    +0

    Ne demek "trust fron example1.com ve example2.com" ile ne demek istiyorsun - bunu nasıl yapabilirim? Teşekkür ederiz – Jenan

    +0

    Web uygulamalarınızda kullandığınız mantık budur. Örneğin, geçerli uygulama tarafından gönderilen özel istekler ile başka bir alanın kimlik doğrulaması ve yetkilendirmesi. –

    İlgili konular