2016-05-18 7 views
11

मैं प्राधिकरण कोड प्रवाह का उपयोग कर AspNet कोर के साथ पहचान सर्वर 4 को लागू करने का प्रयास कर रहा हूं।पहचान सर्वर 4 प्रमाणीकरण कोड प्रवाह उदाहरण

बात यह है कि IdentityServer4 गिथब पर भंडार में कई नमूने हैं, लेकिन प्राधिकरण कोड प्रवाह के साथ कोई भी नहीं है।

किसी को कैसे पहचान सर्वर 4 के साथ प्राधिकरण कोड फ्लो को लागू करने पर एक नमूना और MVC में ग्राहकों का यह लेने वाली है?

उत्तर

21

यहाँ पहचान सर्वर 4 और यह उपभोग करने के लिए एक MVC ग्राहक के साथ एक प्राधिकरण कोड प्रवाह के एक कार्यान्वयन है।

IdentityServer4 हमारे MVC ग्राहक रजिस्टर करने के लिए एक client.cs फ़ाइल का उपयोग कर सकते हैं, यह clientid, ClientSecret की अनुमति अनुदान प्रकार (इस मामले में प्राधिकरण कोड), और हमारे ग्राहक की RedirectUri है:

public class Clients 
{ 
    public static IEnumerable<Client> Get() 
    { 
     var secret = new Secret { Value = "mysecret".Sha512() }; 

     return new List<Client> { 
      new Client { 
       ClientId = "authorizationCodeClient2", 
       ClientName = "Authorization Code Client", 
       ClientSecrets = new List<Secret> { secret }, 
       Enabled = true, 
       AllowedGrantTypes = new List<string> { "authorization_code" }, //DELTA //IdentityServer3 wanted Flow = Flows.AuthorizationCode, 
       RequireConsent = true, 
       AllowRememberConsent = false, 
       RedirectUris = 
        new List<string> { 
         "http://localhost:5436/account/oAuth2" 
        }, 
       PostLogoutRedirectUris = 
        new List<string> {"http://localhost:5436"}, 
       AllowedScopes = new List<string> { 
        "api" 
       }, 
       AccessTokenType = AccessTokenType.Jwt 
      } 
     }; 
    } 
} 

इस वर्ग IdentityServer4 परियोजना में Startup.cs की ConfigurationServices विधि में संदर्भित है:

:

public void ConfigureServices(IServiceCollection services) 
    { 
     ////Grab key for signing JWT signature 
     ////In prod, we'd get this from the certificate store or similar 
     var certPath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "SscSign.pfx"); 
     var cert = new X509Certificate2(certPath); 

     // configure identity server with in-memory stores, keys, clients and scopes 
     services.AddDeveloperIdentityServer(options => 
      { 
       options.IssuerUri = "SomeSecureCompany"; 
      }) 
      .AddInMemoryScopes(Scopes.Get()) 
      .AddInMemoryClients(Clients.Get()) 
      .AddInMemoryUsers(Users.Get()) 
      .SetSigningCredential(cert); 

     services.AddMvc(); 
    } 

संदर्भ के लिए, उपयोगकर्ता और कार्यक्षेत्र वर्गों ऊपर संदर्भित कर रहे हैं

public static class Users 
{ 
    public static List<InMemoryUser> Get() 
    { 
     return new List<InMemoryUser> { 
      new InMemoryUser { 
       Subject = "1", 
       Username = "user", 
       Password = "pass123", 
       Claims = new List<Claim> { 
        new Claim(ClaimTypes.GivenName, "GivenName"), 
        new Claim(ClaimTypes.Surname, "surname"), //DELTA //.FamilyName in IdentityServer3 
        new Claim(ClaimTypes.Email, "[email protected]"), 
        new Claim(ClaimTypes.Role, "Badmin") 
       } 
      } 
     }; 
    } 
} 

public class Scopes 
{ 
    // scopes define the resources in your system 
    public static IEnumerable<Scope> Get() 
    { 
     return new List<Scope> { 
      new Scope 
      { 
       Name = "api", 
       DisplayName = "api scope", 
       Type = ScopeType.Resource, 
       Emphasize = false, 
      } 
     }; 
    } 
} 

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

public ActionResult SignIn() 
{ 
    var state = Guid.NewGuid().ToString("N"); 

    //Store state using cookie-based authentication middleware 
    this.SaveState(state); 

    //Redirect to IdP to get an Authorization Code 
    var url = idPServerAuthUri + 
     "?client_id=" + clientId + 
     "&response_type=" + response_type + 
     "&redirect_uri=" + redirectUri + 
     "&scope=" + scope + 
     "&state=" + state; 

    return this.Redirect(url); //performs a GET 
} 

संदर्भ के लिए, स्थिरांक हैं और savestate विधि से ऊपर उपयोग किया:

//Client and workflow values 
private const string clientBaseUri = @"http://localhost:5436"; 
private const string validIssuer = "SomeSecureCompany"; 
private const string response_type = "code"; 
private const string grantType = "authorization_code"; 

//IdentityServer4 
private const string idPServerBaseUri = @"http://localhost:5000"; 
private const string idPServerAuthUri = idPServerBaseUri + @"/connect/authorize"; 
private const string idPServerTokenUriFragment = @"connect/token"; 
private const string idPServerEndSessionUri = idPServerBaseUri + @"/connect/endsession"; 

//These are also registered in the IdP (or Clients.cs of test IdP) 
private const string redirectUri = clientBaseUri + @"/account/oAuth2"; 
private const string clientId = "authorizationCodeClient2"; 
private const string clientSecret = "mysecret"; 
private const string audience = "SomeSecureCompany/resources"; 
private const string scope = "api"; 


//Store values using cookie-based authentication middleware 
private void SaveState(string state) 
{ 
    var tempId = new ClaimsIdentity("TempCookie"); 
    tempId.AddClaim(new Claim("state", state)); 

    this.Request.GetOwinContext().Authentication.SignIn(tempId); 
} 

दूसरा MVC कार्रवाई विधि IdenityServer4 द्वारा कहा जाता है के बाद उपयोगकर्ता अपने क्रेडेंशियल्स में प्रवेश करती है और किसी भी प्राधिकरण के बक्से की जाँच करता है।कार्रवाई विधि:

  • क्वेरी स्ट्रिंग
  • पुष्टि राज्य वापस IdentityServer4 को
  • पदों से प्राधिकरण कोड और राज्य पकड़ लेता है एक पहुंच टोकन

के लिए प्राधिकरण कोड का आदान-प्रदान करने के लिए यहां विधि है :

[HttpGet] 
public async Task<ActionResult> oAuth2() 
{ 
    var authorizationCode = this.Request.QueryString["code"]; 
    var state = this.Request.QueryString["state"]; 

    //Defend against CSRF attacks http://www.twobotechnologies.com/blog/2014/02/importance-of-state-in-oauth2.html 
    await ValidateStateAsync(state); 

    //Exchange Authorization Code for an Access Token by POSTing to the IdP's token endpoint 
    string json = null; 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = new Uri(idPServerBaseUri); 
     var content = new FormUrlEncodedContent(new[] 
     { 
       new KeyValuePair<string, string>("grant_type", grantType) 
      ,new KeyValuePair<string, string>("code", authorizationCode) 
      ,new KeyValuePair<string, string>("redirect_uri", redirectUri) 
      ,new KeyValuePair<string, string>("client_id", clientId)    //consider sending via basic authentication header 
      ,new KeyValuePair<string, string>("client_secret", clientSecret) 
     }); 
     var httpResponseMessage = client.PostAsync(idPServerTokenUriFragment, content).Result; 
     json = httpResponseMessage.Content.ReadAsStringAsync().Result; 
    } 

    //Extract the Access Token 
    dynamic results = JsonConvert.DeserializeObject<dynamic>(json); 
    string accessToken = results.access_token; 

    //Validate token crypto 
    var claims = ValidateToken(accessToken); 

    //What is done here depends on your use-case. 
    //If the accessToken is for calling a WebAPI, the next few lines wouldn't be needed. 

    //Build claims identity principle 
    var id = new ClaimsIdentity(claims, "Cookie");    //"Cookie" matches middleware named in Startup.cs 

    //Sign into the middleware so we can navigate around secured parts of this site (e.g. [Authorized] attribute) 
    this.Request.GetOwinContext().Authentication.SignIn(id); 

    return this.Redirect("/Home"); 
} 

यह जांचना कि राज्य प्राप्त हुआ है जो आपको अपेक्षित है CSRF हमलों के खिलाफ की रक्षा:

private async Task<AuthenticateResult> ValidateStateAsync(string state) 
{ 
    //Retrieve state value from TempCookie 
    var authenticateResult = await this.Request 
     .GetOwinContext() 
     .Authentication 
     .AuthenticateAsync("TempCookie"); 

    if (authenticateResult == null) 
     throw new InvalidOperationException("No temp cookie"); 

    if (state != authenticateResult.Identity.FindFirst("state").Value) 
     throw new InvalidOperationException("invalid state"); 

    return authenticateResult; 
} 

यह ValidateToken विधि माइक्रोसॉफ्ट के System.IdentityModel और System.IdentityModel.Tokens.Jwt उपयोग करता है: http://www.twobotechnologies.com/blog/2014/02/importance-of-state-in-oauth2.html

यह ValidateStateAsync विधि को प्राप्त राज्य तुलना क्या कुकी मिडलवेयर में बंद बचा लिया गया था यह जांचने के लिए पुस्तकालयों कि जेडब्ल्यूटी को सही तरीके से हस्ताक्षरित किया गया है।

private IEnumerable<Claim> ValidateToken(string token) 
{ 
    //Grab certificate for verifying JWT signature 
    //IdentityServer4 also has a default certificate you can might reference. 
    //In prod, we'd get this from the certificate store or similar 
    var certPath = Path.Combine(Server.MapPath("~/bin"), "SscSign.pfx"); 
    var cert = new X509Certificate2(certPath); 
    var x509SecurityKey = new X509SecurityKey(cert); 

    var parameters = new TokenValidationParameters 
    { 
     RequireSignedTokens = true, 
     ValidAudience = audience, 
     ValidIssuer = validIssuer, 
     IssuerSigningKey = x509SecurityKey, 
     RequireExpirationTime = true, 
     ClockSkew = TimeSpan.FromMinutes(5) 
    }; 

    //Validate the token and retrieve ClaimsPrinciple 
    var handler = new JwtSecurityTokenHandler(); 
    SecurityToken jwt; 
    var id = handler.ValidateToken(token, parameters, out jwt); 

    //Discard temp cookie and cookie-based middleware authentication objects (we just needed it for storing State) 
    this.Request.GetOwinContext().Authentication.SignOut("TempCookie"); 

    return id.Claims; 
} 

इन स्रोत फ़ाइलों से युक्त एक काम कर समाधान https://github.com/bayardw/IdentityServer4.Authorization.Code

+2

वाह! पूरा जवाब के लिए धन्यवाद! –

+3

मुझे कुछ परेशानी हो रही है, ऐसा लगता है कि सभी ट्यूटोरियल/उत्तर पहचानकर्ता सर्वर के कुछ पुराने रूप का उपयोग कर रहे हैं। मुझे पता है कि यह सीधे एक संस्करण 4 के उद्देश्य से एक सवाल है; हालांकि, उनके प्रलेखन पृष्ठ पर भी विसंगतियां हैं। उदाहरण के लिए, उनके पास अब 'AddInMemoryScopes',' AddImMemoryUsers', और कोई मानक 'उपयोगकर्ता' श्रेणी नहीं है। http://docs.identityserver.io/en/release/configuration/startup.html – Adrian

4

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

https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/5_HybridFlowAuthenticationWithApiAccess

+5

पर GitHub पर रहता है आपका लिंक टूटी हुई है। यही कारण है कि आपको सभी महत्वपूर्ण भागों को उत्तर में ही रखना चाहिए। –

+0

हाय डोमिनिक, मुझे लगता है [यह] (https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/5_HybridFlowAuthenticationWithApiAccess) अब उपयोग करने के लिए एक बेहतर लिंक है? – DavidG

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