如何解码SessionSecurityToken

时间:2013-10-11 08:25:13

标签: .net-4.5 wif thinktecture-ident-server thinktecture-ident-model

是否可以解码SessionSecurityToken

我已经使用ThinkTecture IdentityServer设置了一个与MachineKeySessionSecurityTokenHandler合作的网站,一切都按预期工作。
但现在我需要将令牌传递给另一个服务,但是在Authorization HTTP头而不是cookie中。

我尝试了以下内容:

var cookie = HttpContext.Current.Request.Cookies[FederatedAuthentication.FederationConfiguration.CookieHandler.Name];

if (cookie != null)
{
    var t = MachineKey.Unprotect(Convert.FromBase64String(cookie.Value), "System.IdentityModel.Services.MachineKeyTransform");
}

但这会引发System.Security.Cryptography.CryptographicException

1 个答案:

答案 0 :(得分:1)

找到了解决方案。

通过网络发送数据的唯一(简单)方法是将SessionSecurityToken转换为JwtSecurityToken并使用RawData属性。

示例实现(取决于ThinkTecture.IdentityModel):

public JwtSecurityToken ConvertSessionToJsonWebSecurityToken(SessionSecurityToken sessionToken)
{
    var h = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers[typeof(JwtSecurityToken)] as JwtSecurityTokenHandler;

    if (h != null)
    {
        var issuer = ((ValidatingIssuerNameRegistry)h.Configuration.IssuerNameRegistry).IssuingAuthorities.First().Name;
        var audience = h.Configuration.AudienceRestriction.AllowedAudienceUris.First().AbsoluteUri;
        var signingKey = ((ValidatingIssuerNameRegistry)h.Configuration.IssuerNameRegistry).IssuingAuthorities.First().SymmetricKeys.First();
        var securityKey = ((NamedKeyIssuerTokenResolver)h.Configuration.IssuerTokenResolver).SecurityKeys.First().Value.First();

        // Create token
        var t = h.CreateToken(
            null,
            null,
            (ClaimsIdentity)sessionToken.ClaimsPrincipal.Identity,
            new Lifetime(sessionToken.ValidFrom, sessionToken.ValidTo),
            new SigningCredentials(
                securityKey,
                Algorithms.HmacSha256Signature,
                Algorithms.Sha256Digest));

        // Serialize token for validaiton
        var s = h.WriteToken(t);

        // Validate token
        var validationParameters = new TokenValidationParameters()
        {
            AllowedAudience = audience,
            ValidIssuer = issuer,
            SigningToken = new BinarySecretSecurityToken(Convert.FromBase64String(signingKey))
        };

        h.ValidateToken(s, validationParameters);

        // Return token with correct type
        return h.ReadToken(s) as JwtSecurityToken;
    }

    return null;
}

[Test]
public void GetToken_WhenValidSessionTokenExist_ShouldReturnValidJwtToken()
{
    JwtSecurityToken c;
    FederatedAuthentication.SessionAuthenticationModule.TryReadJwtTokenFromCookie(container.GetInstance<ISecurityTokenOperations>(), out c)

    Assert.That(!string.IsNullOrEmpty(c.RawData));
}