2016-10-01 9 views
5

का उपयोग करते हुए एमवीसी कोर ऐप में एमवीसी कोर ऐप में एक्सेस टोकन को रीफ्रेश करने के सर्वोत्तम अभ्यास, मैं एमवीसी कोर एप्लिकेशन का उपयोग करते समय एक्सेस को सर्वोत्तम रूप से कार्यान्वित करने और टोकन रीफ्रेश करने के तरीके को पढ़ रहा हूं (वीडियो देख रहा हूं) इसमें बहुत सारे AJAX कॉल। मुझे लगता है कि मुझे यह सही मिला लेकिन सिर्फ यह जानना चाहता था कि ऐसा करने का एक बेहतर तरीका है या नहीं। मैं इस पोस्ट को संपादित करूंगा ताकि यह इस जानकारी की तलाश में किसी के लिए संदर्भ के रूप में कार्य कर सके।पहचान प्रक्रिया 4

मेरा सेटअप: मेरे पास बहुत सारी जावास्क्रिप्ट के साथ एक एमवीसी कोर एप्लिकेशन है। जावाकॉन जेसन या कॉल क्रियाओं को पुनः प्राप्त करने के लिए AJAX कॉल का उपयोग कर रहे हैं।

चूंकि मैं नहीं चाहता कि मेरे उपयोगकर्ता कुकी प्रमाणीकरण का उपयोग करके मेरे एपीआई तक पहुंच सकें, मैं ऐप का उपयोग कर रहा हूं। मैप को दो हिस्सों में विभाजित करने के लिए। एक जहां उपयोगकर्ता पहचान टोकन का उपयोग करके दृश्यों तक पहुंच सकते हैं और एक को एक्सेस टोकन की आवश्यकता होगी। मैं उस समय को पकड़ने के लिए एक कुकी भी जोड़ रहा हूं जब मुझे अपना एक्सेस टोकन रीफ्रेश करना होगा।

Startup.cs नियंत्रक को कार्रवाई के लिए इस यूआरएल/API/का उपयोग किया जाता है

app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
    AuthenticationScheme = "Cookies", 
    AutomaticAuthenticate = true, 
    ExpireTimeSpan = TimeSpan.FromMinutes(60) 
    }); 

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 

    var oidcOptions = new OpenIdConnectOptions 
    { 
    AuthenticationScheme = "oidc", 
    SignInScheme = "Cookies", 

    Authority = LoginServerUrl, 
    RequireHttpsMetadata = false, 
    ClientId = "MyApp", 
    ClientSecret = "*****", 
    ResponseType = "code id_token", 
    SaveTokens = true, 
    Events = new OpenIdConnectEvents() 
    { 
     OnTicketReceived = async notification => 
     { 
     notification.Response.Cookies.Append("NextAccessTokenRefresh", DateTime.Now.AddMinutes(30).ToString()); 
     notification.Response.Cookies.Delete("AccessToken"); 
     }, 
    }, 

    TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters 
    { 
     NameClaimType = JwtClaimTypes.Name, 
     RoleClaimType = JwtClaimTypes.Role, 
    }, 
    }; 

    oidcOptions.Scope.Clear(); 
    oidcOptions.Scope.Add("openid"); 
    oidcOptions.Scope.Add("roles"); 
    oidcOptions.Scope.Add("offline_access"); 

    app.UseOpenIdConnectAuthentication(oidcOptions); 

    app.Map("/api", (context) => 
    { 
    var bearerTokenOptions = new IdentityServerAuthenticationOptions 
    { 
     AuthenticationScheme = "Bearer", 
     Authority = LoginServerUrl,, 
     RequireHttpsMetadata = false, 
     ScopeName = "MyApi", 
     AutomaticAuthenticate = true 
    }; 

    context.UseIdentityServerAuthentication(bearerTokenOptions); 
    context.UseMvcWithDefaultRoute(); 
    }); 

सभी ajax कॉल (मैं भागों कि importent नहीं है हटाया) [नियंत्रक]/[लड़ाई]।

मैं नहीं चाहता कि मेरा एपीआई पहचान टोकन का उपयोग करके सुलभ हो, इसलिए मैं नियंत्रक कार्रवाई में प्राधिकरण (ActiveAuthenticationSchemes = "Bearer") विशेषता भी जोड़ता हूं। तो अब मेरी नियंत्रक क्रियाएँ जावास्क्रिप्ट से बुलाया जा रहा है इस तरह दिखता है:

[HttpPost, Authorize(ActiveAuthenticationSchemes = "Bearer")] 
public async Task<JsonResult> DoStuff() 
{ 
} 

जब जावास्क्रिप्ट एक एपीआई संसाधन का उपयोग करने की जरूरत है एक, controler पहले पहुँच टोकन retrives और एक कस्टम जावास्क्रिप्ट init का उपयोग कर जावास्क्रिप्ट में injects तरीका।

यह सी # विधि एक्सेस कुकी को रीफ्रेश करने और पुनर्प्राप्त करने के लिए ज़िम्मेदार है।

beforeSend: function(xhr, settings) { xhr.setRequestHeader('Authorization','Bearer ' + accessToken); } 

Thats यह:

public async Task<string> GetAccessTokenAsync() 
{ 
    var accessToken = _contextAccessor.HttpContext.Request.Cookies["AccessToken"]; 
    var nextAccessTokenRefresh = _contextAccessor.HttpContext.Request.Cookies["NextAccessTokenRefresh"]; 
    if (string.IsNullOrEmpty(nextAccessTokenRefresh) || string.IsNullOrEmpty(accessToken) || DateTime.Parse(nextAccessTokenRefresh) <= DateTime.Now) 
    { 
    var refreshToken = await _contextAccessor.HttpContext.Authentication.GetTokenAsync("refresh_token"); 
    var tokenClient = new TokenClient(_appSettings.LoginServerUrl + "/connect/token", _appSettings.LoginClientId, _appSettings.LoginClientSecret); 
    var response = await tokenClient.RequestRefreshTokenAsync(refreshToken); 
    accessToken = response.AccessToken; 

    //Set cookies for next refresh 
    _contextAccessor.HttpContext.Response.Cookies.Append("NextAccessTokenRefresh", DateTime.Now.AddMinutes(30).ToString()); 
    _contextAccessor.HttpContext.Response.Cookies.Append("AccessToken", response.AccessToken); 
    } 

    return accessToken; 
} 
मेरे सारे $ .ajax मैं निम्नलिखित पैरामीटर को शामिल किया है पर

। डिफ़ॉल्ट पहुंच टोकन समाप्ति एक घंटा है। मैं उस समय आधे के बाद हमेशा इसे ताज़ा करता हूं।

अब अपने सवालों के:

  1. मैं किसी भी तरह से मेरी कोड में सुधार कर सकते हैं?
  2. क्या आप इस तरह से कोई सुरक्षा संबंधी जोखिम देख रहे हैं?
  3. क्या मैं ऑनटिकेट में एक्सेस टोकन पुनर्प्राप्त कर सकता हूं?
+1

मैं के रूप में विषय से हटकर है क्योंकि यह एक कोड की समीक्षा के लिए पूछ रहा है इस सवाल के बंद करने के लिए मतदान कर रहा हूँ; कोड समीक्षा ऑफ-विषय हैं। आपको http://codereview.stackexchange.com/ –

+0

पर पूछने की आवश्यकता है, मुझे पता है कि यह थोड़ा सा विषय है, लेकिन आईडी 4 का उपयोग करने वाले बहुत से लोग इस जानकारी की तलाश में हैं। मैं कई अलग-अलग मंचों पर एक ही प्रश्न देख रहा हूं, इसलिए मैंने सोचा कि मैं उन सभी का जवाब देने के लिए यहां एक पोस्ट करूँगा। मैं एक ब्लॉग पोस्ट कर सकता था, लेकिन देव यहां जानकारी की तलाश कर रहे थे। क्या ऐसा कोई स्थान नहीं होना चाहिए जहां आपको इस तरह की जानकारी मिलती है? –

+0

फिर आपको इसे एक और तरीके से वाक्यांश देने की कोशिश करनी चाहिए ताकि आप 1) कोड समीक्षा की मांग न करें, 2) सर्वोत्तम प्रथाओं के लिए नहीं पूछना (जो आमतौर पर केवल 'मुख्य रूप से राय-आधारित' होता है)। –

उत्तर

3

क्या मैं अपना कोड किसी भी तरह से सुधार सकता हूं?

आपका Startup.cs कुछ इस तरह होना चाहिए (क्योंकि केवल '/ API' पथ के लिए Map काम करता है के लिए और अधिक जानकारी https://docs.asp.net/en/latest/fundamentals/middleware.html#run-map-and-use देखें।):

app.MapWhen(context => !context.Request.Path.Value.StartsWith("/api"), builder=> 
{ 
    app.UseCookieAuthentication(options); 
    ... 
    app.UseOpenIdConnectAuthentication(oidcOptions); 
    .... 
}); 

app.MapWhen(context => context.Request.Path.Value.StartsWith("/api"), builder=> 
{ 
    var bearerTokenOptions = new IdentityServerAuthenticationOptions 
    { 
     AuthenticationScheme = "Bearer", 
     Authority = LoginServerUrl,, 
     RequireHttpsMetadata = false, 
     ScopeName = "MyApi", 
     AutomaticAuthenticate = true 
    }; 

    context.UseIdentityServerAuthentication(bearerTokenOptions); 
    context.UseMvcWithDefaultRoute(); 
}); 

दूसरा बिंदु, अपने कुकी समाप्त हो समय 60 मिनट है, इस मामले में आपका ताज़ा टोकन का जीवनकाल 60 मिनट होगा। मुझे लगता है कि यह एक समस्या हो सकती है।

क्या आप इस तरह से कोई सुरक्षा संबंधी जोखिम देख रहे हैं?

मुझे ताज़ा टोकन का उपयोग करने के लिए पर्याप्त अनुभव नहीं मिला है, इसलिए मैं यह नहीं कह सकता कि आपका कार्यान्वयन सुरक्षित है या नहीं। लेकिन मुझे लगता है कि रीफ्रेश टोकन (आपके कार्यान्वयन के लिए) जटिलता को सुरक्षा जोखिम भी बढ़ाता है (यह सिर्फ मेरी राय है और मैं सुरक्षा विशेषज्ञ नहीं हूं)। मैं अंतर्निहित प्रवाह (सादगी के कारण) के साथ केवल लंबे समय तक पहुंचने वाली टोकन का उपयोग करूंगा।

क्या मैं ऑनटिकेट में एक्सेस टोकन पुनर्प्राप्त कर सकता हूं?

हाँ, आप कर सकते हैं:

OnTicketReceived = ctx => 
{ 
    var token = ctx.Ticket.Properties.GetTokenValue("access_token"); 
    ... 
} 
+0

आपके उत्कृष्ट उत्तरों के लिए धन्यवाद। मैं नक्शा पथ को और अधिक विशिष्ट होने के लिए बदल दूंगा और ऑनटिकेट रिसीव में कुकीज़ में टोकन स्टोर भी करूंगा। यह सर्वर के लिए एक गोल यात्रा बचाता है। –

+0

मैं लंबे समय तक पहुंचने वाले टोकन का उपयोग करने के बारे में सोच रहा था, लेकिन मुझे उम्मीद है कि जब भी उपयोगकर्ता इंटरैक्शन के बिना कभी भी टोकन को रीफ्रेश करके इसे सुरक्षित बना दिया जा सकता है। यह थोड़ा और जटिल है लेकिन चूंकि मैं केवल अपने सर्वर पर "क्लाइंट गुप्त" संग्रहीत कर रहा हूं, मुझे लगता है कि यह ताज़ा टोकन का उपयोग करके ठीक होना चाहिए। –

+0

लंबे समय तक रहने वाले टोकन का उपयोग करना मेरी प्राथमिकता है (मैं यह नहीं कह सकता कि इसका उपयोग करें)। मैं यथासंभव जटिलता से बचता हूं और मेरी राय में जटिलता एक सुरक्षा जोखिम है। –

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