.NET Core和Azure Active Directory集成

时间:2017-05-30 21:32:23

标签: c# .net-core azure-active-directory

我在Azure Active Directory中使用令牌身份验证(而不是cookie)。

基于这篇文章: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 Core 1.0.3中重新实现上述方法。

基于这篇文章:how to sign and verify signature with net and a certificate

以下行不会在.NET Core上编译:

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

我不确定根据.NET Core中的证书验证令牌的正确方法是什么。

2 个答案:

答案 0 :(得分:2)

验证Azure AD发布的令牌的简单方法是利用Web API的OWIN注释。我们只需要配置JwtBearerOptions并将请求发送到受Azure AD保护的控制器。如果未验证令牌,您将收到401响应。您可以参考代码示例here

如果您想实现代码以手动验证令牌,我们可以参考代码,以便Microsoft在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"
    }
  }
}

答案 1 :(得分:0)

根据此质量检查:implement RSA in .NET core您的cert对象应该有一个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