2012-04-09 31 views
0

を取得し、生のトークンからトークン出ACSを取得する方法この記事でValidating a SWT Token REST WCF Service我々はアイデンティティプロバイダ

を説明するように、私は、ACSからトークンを取得しています。しかし、私は、ACSのトークンを抽出することができませんでした。 それで私を助けてください。 実際にはクラスは、ACSトークン "JsonNotifyRequestSecurityTokenResponse.FromJson"を抽出します 提供されたリンクが機能していないため、クラスとして取得できませんでした。

+0

私はあなたの質問に答え以来こんにちは、それは一週間前にすでにです。助けてくれたの?いいえの場合:コメントを追加し、はいの場合は答えを受け入れます。 – Robar

答えて

0

私は数時間前に私の質問でこの質問を回答として投稿し、それを削除したと思います。だから私は私の古いプロジェクトを見て、あなたが必要とするコードが見つかりました:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.IdentityModel.Policy; 
using System.IdentityModel.Tokens; 
using System.IO; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Json; 
using System.Text; 
using System.Web; 
using System.Xml.Linq; 
using Thinktecture.IdentityModel.Extensions; 

namespace Security { 
    [DataContract] 
    public class JsonNotifyRequestSecurityTokenResponse { 
     [DataMember(Name = "appliesTo", Order = 1)] 
     public string AppliesTo { get; set; } 

     [DataMember(Name = "context", Order = 2)] 
     public string Context { get; set; } 

     [DataMember(Name = "created", Order = 3)] 
     public string Created { get; set; } 

     [DataMember(Name = "expires", Order = 4)] 
     public string Expires { get; set; } 

     [DataMember(Name = "securityToken", Order = 5)] 
     public string SecurityTokenString { get; set; } 

     [DataMember(Name = "tokenType", Order = 6)] 
     public string TokenType { get; set; } 

     public DateTime ValidFrom { get; set; } 
     public DateTime ValidTo { get; set; } 
     public GenericXmlSecurityToken SecurityToken { get; set; } 

     public static JsonNotifyRequestSecurityTokenResponse FromJson(string jsonString) { 
      JsonNotifyRequestSecurityTokenResponse rstr; 

      var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)); 
      var serializer = new DataContractJsonSerializer(typeof(JsonNotifyRequestSecurityTokenResponse)); 

      rstr = serializer.ReadObject(memoryStream) as JsonNotifyRequestSecurityTokenResponse; 
      memoryStream.Close(); 

      ParseValues(rstr); 
      return rstr; 
     } 

     private static void ParseValues(JsonNotifyRequestSecurityTokenResponse rstr) { 
      rstr.ValidFrom = ulong.Parse(rstr.Created).ToDateTimeFromEpoch(); 
      rstr.ValidTo = ulong.Parse(rstr.Expires).ToDateTimeFromEpoch(); 
      rstr.SecurityTokenString = HttpUtility.HtmlDecode(rstr.SecurityTokenString); 
      var xml = XElement.Parse(rstr.SecurityTokenString); 

      string idAttribute = ""; 
      string tokenType = ""; 

      switch (rstr.TokenType) { 
       case SecurityTokenTypes.Saml11: 
        idAttribute = "AssertionID"; 
        tokenType = SecurityTokenTypes.Saml11; 
        break; 
       case SecurityTokenTypes.Saml2: 
        idAttribute = "ID"; 
        tokenType = SecurityTokenTypes.Saml2; 
        break; 
       case SecurityTokenTypes.SWT: 
        idAttribute = "Id"; 
        tokenType = SecurityTokenTypes.SWT; 
        break; 
      } 

      if (tokenType == SecurityTokenTypes.Saml11 || tokenType == SecurityTokenTypes.Saml2) { 
       var tokenId = xml.Attribute(idAttribute); 
       var xmlElement = xml.ToXmlElement(); 
       SecurityKeyIdentifierClause clause = null; 

       if (tokenId != null) { 
        clause = new SamlAssertionKeyIdentifierClause(tokenId.Value); 
       } 

       rstr.SecurityToken = new GenericXmlSecurityToken(
        xmlElement, 
        null, 
        rstr.ValidFrom, 
        rstr.ValidTo, 
        clause, 
        clause, 
        new ReadOnlyCollection<IAuthorizationPolicy>(new List<IAuthorizationPolicy>())); 
      } 
     } 

     private class SecurityTokenTypes { 
      public const string Saml2 = "urn:oasis:names:tc:SAML:2.0:assertion"; 
      public const string Saml11 = "urn:oasis:names:tc:SAML:1.0:assertion"; 
      public const string SWT = "http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0"; 
     } 
    } 
} 

あなたがからThinktecture.IdentityModel.Extensionsアセンブリを取得する必要があります:http://identitymodel.codeplex.com/

私はこのことができます願っています。

EDIT - SWTトークン取り扱い

それは場合に役立ちます私は知らないが、私はSWTトークンを処理する必要がありますSWTModuleを見つけました。

public class SWTModule : IHttpModule { 

    void IHttpModule.Dispose() { 

    } 

    void IHttpModule.Init(HttpApplication context) { 
     context.BeginRequest += new EventHandler(context_BeginRequest); 
    } 

    void context_BeginRequest(object sender, EventArgs e) { 
     //HANDLE SWT TOKEN VALIDATION 
     // get the authorization header 
     string headerValue = HttpContext.Current.Request.Headers.Get("Authorization"); 

     // check that a value is there 
     if (string.IsNullOrEmpty(headerValue)) { 
      throw new ApplicationException("unauthorized"); 
     } 

     // check that it starts with 'WRAP' 
     if (!headerValue.StartsWith("WRAP ")) { 
      throw new ApplicationException("unauthorized"); 
     } 

     string[] nameValuePair = headerValue.Substring("WRAP ".Length).Split(new char[] { '=' }, 2); 

     if (nameValuePair.Length != 2 || 
      nameValuePair[0] != "access_token" || 
      !nameValuePair[1].StartsWith("\"") || 
      !nameValuePair[1].EndsWith("\"")) { 
      throw new ApplicationException("unauthorized"); 
     } 

     // trim off the leading and trailing double-quotes 
     string token = nameValuePair[1].Substring(1, nameValuePair[1].Length - 2); 

     // create a token validator 
     TokenValidator validator = new TokenValidator(
      this.acsHostName, 
      this.serviceNamespace, 
      this.trustedAudience, 
      this.trustedTokenPolicyKey); 

     // validate the token 
     if (!validator.Validate(token)) { 
      throw new ApplicationException("unauthorized"); 
     } 

    } 
} 

そして、あなたもTokenValidatorが必要です

public class TokenValidator { 
    private string issuerLabel = "Issuer"; 
    private string expiresLabel = "ExpiresOn"; 
    private string audienceLabel = "Audience"; 
    private string hmacSHA256Label = "HMACSHA256"; 

    private string acsHostName; 

    private string trustedSigningKey; 
    private string trustedTokenIssuer; 
    private string trustedAudienceValue; 

    public TokenValidator(string acsHostName, string serviceNamespace, string trustedAudienceValue, string trustedSigningKey) { 
     this.trustedSigningKey = trustedSigningKey; 
     this.trustedTokenIssuer = String.Format("https://{0}.{1}/", 
      serviceNamespace.ToLowerInvariant(), 
      acsHostName.ToLowerInvariant()); 

     this.trustedAudienceValue = trustedAudienceValue; 
    } 

    public bool Validate(string token) { 
     if (!this.IsHMACValid(token, Convert.FromBase64String(this.trustedSigningKey))) { 
      return false; 
     } 

     if (this.IsExpired(token)) { 
      return false; 
     } 

     if (!this.IsIssuerTrusted(token)) { 
      return false; 
     } 

     if (!this.IsAudienceTrusted(token)) { 
      return false; 
     } 

     return true; 
    } 

    public Dictionary<string, string> GetNameValues(string token) { 
     if (string.IsNullOrEmpty(token)) { 
      throw new ArgumentException(); 
     } 

     return 
      token 
      .Split('&') 
      .Aggregate(
      new Dictionary<string, string>(), 
      (dict, rawNameValue) => { 
       if (rawNameValue == string.Empty) { 
        return dict; 
       } 

       string[] nameValue = rawNameValue.Split('='); 

       if (nameValue.Length != 2) { 
        throw new ArgumentException("Invalid formEncodedstring - contains a name/value pair missing an = character"); 
       } 

       if (dict.ContainsKey(nameValue[0]) == true) { 
        throw new ArgumentException("Repeated name/value pair in form"); 
       } 

       dict.Add(HttpUtility.UrlDecode(nameValue[0]), HttpUtility.UrlDecode(nameValue[1])); 
       return dict; 
      }); 
    } 

    private static ulong GenerateTimeStamp() { 
     // Default implementation of epoch time 
     TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); 
     return Convert.ToUInt64(ts.TotalSeconds); 
    } 

    private bool IsAudienceTrusted(string token) { 
     Dictionary<string, string> tokenValues = this.GetNameValues(token); 

     string audienceValue; 

     tokenValues.TryGetValue(this.audienceLabel, out audienceValue); 

     if (!string.IsNullOrEmpty(audienceValue)) { 
      if (audienceValue.Equals(this.trustedAudienceValue, StringComparison.Ordinal)) { 
       return true; 
      } 
     } 

     return false; 
    } 

    private bool IsIssuerTrusted(string token) { 
     Dictionary<string, string> tokenValues = this.GetNameValues(token); 

     string issuerName; 

     tokenValues.TryGetValue(this.issuerLabel, out issuerName); 

     if (!string.IsNullOrEmpty(issuerName)) { 
      if (issuerName.Equals(this.trustedTokenIssuer)) { 
       return true; 
      } 
     } 

     return false; 
    } 

    private bool IsHMACValid(string swt, byte[] sha256HMACKey) { 
     string[] swtWithSignature = swt.Split(new string[] { "&" + this.hmacSHA256Label + "=" }, StringSplitOptions.None); 

     if ((swtWithSignature == null) || (swtWithSignature.Length != 2)) { 
      return false; 
     } 

     HMACSHA256 hmac = new HMACSHA256(sha256HMACKey); 

     byte[] locallyGeneratedSignatureInBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(swtWithSignature[0])); 

     string locallyGeneratedSignature = HttpUtility.UrlEncode(Convert.ToBase64String(locallyGeneratedSignatureInBytes)); 

     return locallyGeneratedSignature == swtWithSignature[1]; 
    } 

    private bool IsExpired(string swt) { 
     try { 
      Dictionary<string, string> nameValues = this.GetNameValues(swt); 
      string expiresOnValue = nameValues[this.expiresLabel]; 
      ulong expiresOn = Convert.ToUInt64(expiresOnValue); 
      ulong currentTime = Convert.ToUInt64(GenerateTimeStamp()); 

      if (currentTime > expiresOn) { 
       return true; 
      } 

      return false; 
     } catch (KeyNotFoundException) { 
      throw new ArgumentException(); 
     } 
    } 
} 
+0

お返事ありがとうございましたRobarと私の遅い返信申し訳ありません実際に私はいくつかの他のassignmnetで忙しかった。 –

+0

お返事ありがとうございました。私の遅い返信には申し訳ありません。しかし、私は質問があります。私がSAML1.1またはSAML2.0トークンを返すように私の信頼当事者を構成するとき。クライアント側では、私はトークンの値を取得しました。しかし、私がSWTトークンを返すようにRelying Partyを設定すると、クライアント側でトークンを取得しますが、あなたのクラスでsaml11とsaml12トークンを処理しているだけです if(tokenType == SecurityTokenTypes.Saml11 || tokenType == SecurityTokenTypes.Saml2 ) SWTトークンを私に助けてください。 –

+0

私は現在仕事中です。私が家に帰ったら、古いプロジェクトのいくつかを調べて、あなたのSWTトークンの問題に役立つものが見つかったかどうかを確認します。 – Robar