2013-04-22 18 views
7

का उपयोग कर सेवा प्रमाणीकरण के लिए वेब एपीआई में एपी कुंजी का उपयोग कैसे करें मैं एमवीसी 4 वेब एपीआई का उपयोग कर रहा हूं और मैं चाहता हूं कि उपयोगकर्ता मेरी सेवा का उपयोग करने से पहले प्रमाणित हों।फॉर्म प्रमाणीकरण

मैंने एक प्राधिकरण संदेश हैंडलर लागू किया है, जो ठीक काम करता है।

public class AuthorizationHandler : DelegatingHandler 
{ 
    private readonly AuthenticationService _authenticationService = new AuthenticationService(); 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     IEnumerable<string> apiKeyHeaderValues = null; 
     if (request.Headers.TryGetValues("X-ApiKey", out apiKeyHeaderValues)) 
     { 
      var apiKeyHeaderValue = apiKeyHeaderValues.First(); 

      // ... your authentication logic here ... 
      var user = _authenticationService.GetUserByKey(new Guid(apiKeyHeaderValue)); 

      if (user != null) 
      { 

       var userId = user.Id; 

       var userIdClaim = new Claim(ClaimTypes.SerialNumber, userId.ToString()); 
       var identity = new ClaimsIdentity(new[] { userIdClaim }, "ApiKey"); 
       var principal = new ClaimsPrincipal(identity); 

       Thread.CurrentPrincipal = principal; 
      } 
     } 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

समस्या यह है कि मैं फॉर्म प्रमाणीकरण का उपयोग करता हूं।

[HttpPost] 
    public ActionResult Login(UserModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = _authenticationService.Login(model); 
      if (user != null) 
      { 
       // Add the api key to the HttpResponse??? 
      } 
      return View(model); 
     } 

     return View(model); 
    } 

जब मैं अपने API कॉल:

[Authorize] 
public class TestController : ApiController 
{ 
    public string GetLists() 
    { 
     return "Weee"; 
    } 
} 

हैंडलर एक्स ApiKey हैडर नहीं मिल रहा।

क्या HTTP प्रतिक्रिया शीर्षलेख में उपयोगकर्ता की एपीआई कुंजी जोड़ने और वहां कुंजी रखने के लिए कोई तरीका है, जब तक कि उपयोगकर्ता लॉग इन हो? क्या इस कार्यक्षमता को लागू करने का कोई और तरीका है?

उत्तर

2

मैं निम्न आलेख http://www.asp.net/web-api/overview/working-with-http/http-cookies यह कुकीज़ का उपयोग करने के लिए अपने AuthorizationHandler का उपयोग करते हुए मैं कॉन्फ़िगर पाया:

यहाँ HttpClient के कुछ उदाहरण हैं

[HttpPost] 
    public ActionResult Login(LoginModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = _authenticationService.Login(model); 
      if (user != null) 
      { 
       _cookieHelper.SetCookie(user); 

       return RedirectToAction("Index", "Home"); 
      } 

      ModelState.AddModelError("", "Incorrect username or password"); 
      return View(model); 
     } 

     return View(model); 
    } 

इसके अंदर मैं कुकी हेल्पर का उपयोग कर रहा हूं, मैंने बनाया है।

public interface ICookieHelper 
{ 
    void SetCookie(User user); 

    void RemoveCookie(); 

    Guid GetUserId(); 
} 

और एक वर्ग है कि इंटरफ़ेस लागू करता है:: यह एक इंटरफेस के होते हैं

public class CookieHelper : ICookieHelper 
{ 
    private readonly HttpContextBase _httpContext; 

    public CookieHelper(HttpContextBase httpContext) 
    { 
     _httpContext = httpContext; 
    } 

    public void SetCookie(User user) 
    { 
     var cookie = new HttpCookie(Constants.ApiKey, user.UserId.ToString()) 
     { 
      Expires = DateTime.UtcNow.AddDays(1) 
     }; 

     _httpContext.Response.Cookies.Add(cookie); 
    } 

    public void RemoveCookie() 
    { 
     var cookie = _httpContext.Response.Cookies[Constants.ApiKey]; 
     if (cookie != null) 
     { 
      cookie.Expires = DateTime.UtcNow.AddDays(-1); 
      _httpContext.Response.Cookies.Add(cookie); 
     } 
    } 

    public Guid GetUserId() 
    { 
     var cookie = _httpContext.Request.Cookies[Constants.ApiKey]; 
     if (cookie != null && cookie.Value != null) 
     { 
      return Guid.Parse(cookie.Value); 
     } 

     return Guid.Empty; 
    } 
} 

इस विन्यास होने से, अब मैं अपने ApiControllers के लिए अधिकृत करें विशेषता का उपयोग कर सकते हैं:

[Authorize] 
public class TestController : ApiController 
{ 
    public string Get() 
    { 
     return String.Empty; 
    } 
} 

इसका मतलब है कि यदि उपयोगकर्ता लॉग इन नहीं है। वह मेरे एपीआई तक नहीं पहुंच सकता है और 401 त्रुटि प्राप्त करता है। इसके अलावा मैं एपीआई कुंजी पुनर्प्राप्त कर सकता हूं, जिसे मैं अपने आईडी में कहीं भी उपयोगकर्ता आईडी के रूप में उपयोग करता हूं, जो इसे बहुत साफ और पठनीय बनाता है।

मुझे नहीं लगता कि कुकीज़ का उपयोग करना सबसे अच्छा समाधान है, क्योंकि कुछ उपयोगकर्ता ने उन्हें अपने ब्राउज़र में अक्षम कर दिया है, लेकिन फिलहाल मुझे प्राधिकरण करने का बेहतर तरीका नहीं मिला है।

1

अपने कोड नमूने से ऐसा लगता है कि आप वेब फॉर्म का उपयोग नहीं कर रहे हैं। क्या आप प्रपत्र प्रमाणीकरण का उपयोग कर रहे हैं? क्या आप उपयोगकर्ता प्रमाण-पत्रों को सत्यापित करने के लिए अपनी सेवा के भीतर सदस्यता प्रदाता का उपयोग कर रहे हैं?

आप एचटीपी क्लाइंट क्लास का उपयोग कर सकते हैं और शायद इसकी संपत्ति DefaultRequestHeaders या HttpRequestMessage कोड से है जो एपीआई को हेडर सेट करने के लिए बुलाएगा।

public class AuthorizationHandler : DelegatingHandler 
{ 
    private readonly IAuthenticationService _authenticationService = new AuthenticationService(); 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var cookie = request.Headers.GetCookies(Constants.ApiKey).FirstOrDefault(); 
     if (cookie != null) 
     { 
      var apiKey = cookie[Constants.ApiKey].Value; 
      try 
      { 
       var guidKey = Guid.Parse(apiKey); 

       var user = _authenticationService.GetUserByKey(guidKey); 
       if (user != null) 
       { 

        var userIdClaim = new Claim(ClaimTypes.Name, apiKey); 
        var identity = new ClaimsIdentity(new[] { userIdClaim }, "ApiKey"); 
        var principal = new ClaimsPrincipal(identity); 

        Thread.CurrentPrincipal = principal; 

       } 
      } 
      catch (FormatException) 
      { 
      } 
     } 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

मैं अपने लॉग इन कार्रवाई परिणाम कॉन्फ़िगर किया गया: http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

+0

धन्यवाद! आप सही हैं मेरा मतलब प्रपत्र प्रमाणीकरण था। मैंने अपना प्रश्न संपादित किया। मैं सदस्यता प्रदाता का उपयोग नहीं कर रहा हूं, इसके बजाय मैंने कस्टम प्रमाणीकरण तर्क बनाया है। मैं HttpRequestMessage का उपयोग नहीं कर सकता, क्योंकि मैं एमवीसी नियंत्रक का उपयोग करके अपना कार्यप्रणाली कर रहा हूं और एक क्रिया परिणाम लौटा रहा हूं (या मुझे इसका उपयोग करने के तरीके के बारे में पता नहीं है)। –

संबंधित मुद्दे