2017-05-30 167 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中不可用。 –