如何在SecurityTokenResolver中禁用主题密钥标识符 [英] How to disable Subject Key Identifier in SecurityTokenResolver

查看:108
本文介绍了如何在SecurityTokenResolver中禁用主题密钥标识符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理包含EncryptedAssertion的WIF中的SAML2令牌.标记不包含主题标识符密钥"扩展属性,因此WIF SecurityTokenHandler失败,因为它试图从LocalMachineStore/Personal获取正确的X509证书.

问题显然是,用于加密令牌的证书不包含SKI扩展,当然令牌生成代码(Java)似乎并不需要它.为避免不得不修改生成代码,有一种方法可以让WIF SecuityTokenResolver不检查SKI的已接收令牌,而直接使用本地存储证书直接对令牌进行解密?

最后,我只是实现了一个自定义的SecurityTokenResolver并实现了TryResolveSecurityKeyCore方法.

这是代码:

public class mySaml2SSOSecurityTokenResolver : SecurityTokenResolver
{
    List<SecurityToken> _tokens;

    public PortalSSOSecurityTokenResolver(List<SecurityToken> tokens)
    {
        _tokens = tokens;
    }
    protected override bool TryResolveSecurityKeyCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityKey key)
    {
        var token = _tokens[0] as X509SecurityToken;

        var myCert = token.Certificate;

        key = null;

        try
        {

            var ekec = keyIdentifierClause as EncryptedKeyIdentifierClause;

            if (ekec != null)
            {

                switch (ekec.EncryptionMethod)
                {

                    case "http://www.w3.org/2001/04/xmlenc#rsa-1_5":
                        {
                            var encKey = ekec.GetEncryptedKey();

                            var rsa = myCert.PrivateKey as RSACryptoServiceProvider;

                            var decKey = rsa.Decrypt(encKey, false);

                            key = new InMemorySymmetricSecurityKey(decKey);

                            return true;

                        }

                }

                var data = ekec.GetEncryptedKey();

                var id = ekec.EncryptingKeyIdentifier;

            }

        }

        catch (Exception ex)
        {
           // Do something here            }

            return true;

    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifier keyIdentifier, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }
}

}

I am processing a SAML2 token in WIF which contains an EncryptedAssertion. The mark-up does NOT contain a "Subject Identifier Key" Extension property and as such WIF SecurityTokenHandler fails as it tries to get the correct X509 certificate from the LocalMachineStore/Personal.

The issue is clearly that the certificate used to encrypt the token does not contain the SKI Extension and of course the token generation code (Java) does not do seem to require it. To avoid having to modify the generation code is there a way I can get WIF SecuityTokenResolver to NOT check the received Token for the SKI but simply use the local store certificate directly to decrypt the token?

解决方案

In the end I just implemented a custom SecurityTokenResolver and implemented the TryResolveSecurityKeyCore method.

Here is the code:

public class mySaml2SSOSecurityTokenResolver : SecurityTokenResolver
{
    List<SecurityToken> _tokens;

    public PortalSSOSecurityTokenResolver(List<SecurityToken> tokens)
    {
        _tokens = tokens;
    }
    protected override bool TryResolveSecurityKeyCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityKey key)
    {
        var token = _tokens[0] as X509SecurityToken;

        var myCert = token.Certificate;

        key = null;

        try
        {

            var ekec = keyIdentifierClause as EncryptedKeyIdentifierClause;

            if (ekec != null)
            {

                switch (ekec.EncryptionMethod)
                {

                    case "http://www.w3.org/2001/04/xmlenc#rsa-1_5":
                        {
                            var encKey = ekec.GetEncryptedKey();

                            var rsa = myCert.PrivateKey as RSACryptoServiceProvider;

                            var decKey = rsa.Decrypt(encKey, false);

                            key = new InMemorySymmetricSecurityKey(decKey);

                            return true;

                        }

                }

                var data = ekec.GetEncryptedKey();

                var id = ekec.EncryptingKeyIdentifier;

            }

        }

        catch (Exception ex)
        {
           // Do something here            }

            return true;

    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifier keyIdentifier, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }
}

}

这篇关于如何在SecurityTokenResolver中禁用主题密钥标识符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆