2017-05-30 152 views
1

我對Azure Active Directory使用了令牌認證(而不是cookie)。.NET核心和Azure Active Directory集成

基於這篇文章:https://www.itunity.com/article/angular-2-openid-connect-azure-active-directory-3093

我能得到它的工作在客戶端。

public validateSignature(token): Observable<boolean> { 
     /* Retrieve from federated metadata endpoint. 
     In this sample, the document was downloaded locally */ 
     return this.httpService.get("metadata/metadata.xml") 
      .map((res: Response) => { 
       let dom = (new DOMParser()).parseFromString(res.text(), "text/xml"); 
       let json = xml2json(dom, ""); 
       let cert = "-----BEGIN CERTIFICATE-----" + 
       JSON.parse(json).EntityDescriptor[0]["ds:Signature"] 
        ["KeyInfo"]["X509Data"]["X509Certificate"] + 
       "-----END CERTIFICATE-----"; 
       let key = KEYUTIL.getKey(cert); 
       return KJUR.jws.JWS.verifyJWT(token, key, { alg: ['RS256'] }); 
      }) 
     } 

我試圖重新實現在.NET核心1.0.3上述方法。

基於這篇文章:how to sign and verify signature with net and a certificate

下面的行不會編譯.NET的核心:

RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key; 

我不知道什麼是驗證基於證書的令牌正確的方法.NET核心。

回答

2

一個簡單的方法,以驗證由天青AD發出的令牌是與利用網絡API的OWIN評論。我們只需要配置JwtBearerOptions並將請求發送到受Azure AD保護的控制器。如果令牌未被驗證,您將得到401響應。您可以參考代碼示例here

如果您想要實施代碼來手動驗證令牌,我們可以參考代碼如何在Microsoft.AspNetCore.Authentication.JwtBearer中驗證令牌。

我也寫了供您參考的代碼示例:

public class JsonWebTokenValidator 
{ 
    public void Validate(string token) 
    { 
     var stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"; 
     var options = new JwtBearerOptions 
     { 
      ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()), 

      TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() 
      { 
       ValidateIssuer = true, 
       ValidIssuer = "https://sts.windows.net/{tenantId}/", 

       ValidateAudience = true, 
       ValidAudience = "{audience}", 

       RequireExpirationTime = true, 
       ValidateLifetime = true, 

       ValidateIssuerSigningKey = true, 

       ClockSkew = TimeSpan.Zero 
      }, 
      Authority = "https://login.microsoftonline.com/{tenantId}", 
     }; 

     SecurityToken validatedToken = null; 
     ClaimsPrincipal result = null; 
     var configuration = options.ConfigurationManager.GetConfigurationAsync(new CancellationToken()).Result; 
     options.TokenValidationParameters.IssuerSigningKeys = configuration.SigningKeys; 

     options.ConfigurationManager.RequestRefresh(); 
     foreach (var validators in options.SecurityTokenValidators) 
     { 
      result = validators.ValidateToken(token, options.TokenValidationParameters, out validatedToken); 
     } 

     foreach (var claim in result.Claims) 
     { 
      Console.WriteLine($"{claim.Subject}:{claim.Value}"); 
     } 
    } 

Project.json

{ 
    "version": "1.0.0-*", 
    "buildOptions": { 
    "emitEntryPoint": true 
    }, 

    "dependencies": { 
    "Microsoft.IdentityModel.Clients.ActiveDirectory": "3.13.9", 
    "Microsoft.NETCore.App": { 
     "type": "platform", 
     "version": "1.0.1" 
    }, 

    "System.IdentityModel.Tokens.Jwt": { 
     "version": "5.1.3" 
    }, 
    "Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0", 
    "Microsoft.IdentityModel.Protocols": "2.1.3", 
    "Microsoft.IdentityModel.Protocols.OpenIdConnect": "2.0.0" 
    }, 

    "frameworks": { 
    "netcoreapp1.0": { 
     "imports": "dnxcore50" 
    } 
    } 
} 
+0

它按預期工作。謝謝! –

+0

@DerekLiang如果問題有幫助,請將其標記爲答案,以便具有相同問題的社區可以輕鬆識別有用的帖子:) –

+0

我將ValidateIssuerSigningKey設置爲true,但沒有簽名密鑰。當我將SymmetricSecurityKey值添加到IssuerSigningKey屬性時,不管賦予什麼值,都不起作用。我假設它只會驗證我擁有的密鑰。 – RyanOC

0

根據這一QA:implement RSA in .NET corecert對象應該有一個GetRSAPublicKey()方法,該方法返回一個RSA對象 - 只是一定要敷在using,因爲它是IDisposable

static bool Verify(string text, byte[] signature, string certPath) 
{ 
    X509Certificate2 cert = new X509Certificate2(certPath); 

    using(RSA rsa = cert.GetRSAPublicKey()) 
    using(SHA1Managed sha1 = new SHA1Managed()) 
    { 
     byte[] data = Encoding.Unicode.GetBytes(text); 
     byte[] hash = sha1.ComputeHash(data); 

     return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature); 
    } 
} 

顯然GetRSAPublicKey()被定義爲擴展方法:https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.rsacertificateextensions.getrsapublickey(v=vs.110).aspx

+0

在原來的問題,什麼是數據驗證? id_token有3個部分,標題,聲明和簽名由'。'分隔。而且CryptoConfig.MapNameToOID(「SHA1」)在.NET Core中不可用。 –