1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.IdentityModel.Selectors 6 { 7 using System.Collections.ObjectModel; 8 using System.IdentityModel.Configuration; 9 using System.IdentityModel.Tokens; 10 using System.Xml; 11 12 public abstract class SecurityTokenResolver : ICustomIdentityConfiguration 13 { ResolveToken(SecurityKeyIdentifier keyIdentifier)14 public SecurityToken ResolveToken(SecurityKeyIdentifier keyIdentifier) 15 { 16 if (keyIdentifier == null) 17 { 18 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier"); 19 } 20 SecurityToken token; 21 if (!this.TryResolveTokenCore(keyIdentifier, out token)) 22 { 23 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveTokenReference, keyIdentifier))); 24 } 25 return token; 26 } 27 TryResolveToken(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)28 public bool TryResolveToken(SecurityKeyIdentifier keyIdentifier, out SecurityToken token) 29 { 30 if (keyIdentifier == null) 31 { 32 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier"); 33 } 34 return TryResolveTokenCore(keyIdentifier, out token); 35 } 36 ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause)37 public SecurityToken ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause) 38 { 39 if (keyIdentifierClause == null) 40 { 41 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 42 } 43 SecurityToken token; 44 if (!this.TryResolveTokenCore(keyIdentifierClause, out token)) 45 { 46 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveTokenReference, keyIdentifierClause))); 47 } 48 return token; 49 } 50 TryResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)51 public bool TryResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) 52 { 53 if (keyIdentifierClause == null) 54 { 55 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 56 } 57 return this.TryResolveTokenCore(keyIdentifierClause, out token); 58 } 59 ResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause)60 public SecurityKey ResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause) 61 { 62 if (keyIdentifierClause == null) 63 { 64 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 65 } 66 SecurityKey key; 67 if (!this.TryResolveSecurityKeyCore(keyIdentifierClause, out key)) 68 { 69 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveKeyReference, keyIdentifierClause))); 70 } 71 return key; 72 } 73 TryResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)74 public bool TryResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) 75 { 76 if (keyIdentifierClause == null) 77 { 78 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 79 } 80 return this.TryResolveSecurityKeyCore(keyIdentifierClause, out key); 81 } 82 83 /// <summary> 84 /// Load custom configuration from Xml 85 /// </summary> 86 /// <param name="nodelist">Custom configuration elements</param> LoadCustomConfiguration(XmlNodeList nodelist)87 public virtual void LoadCustomConfiguration(XmlNodeList nodelist) 88 { 89 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException(SR.GetString(SR.ID0023, this.GetType().AssemblyQualifiedName))); 90 } 91 92 // protected methods TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)93 protected abstract bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token); TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)94 protected abstract bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token); TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)95 protected abstract bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key); 96 97 CreateDefaultSecurityTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId)98 public static SecurityTokenResolver CreateDefaultSecurityTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId) 99 { 100 return new SimpleTokenResolver(tokens, canMatchLocalId); 101 } 102 103 class SimpleTokenResolver : SecurityTokenResolver 104 { 105 ReadOnlyCollection<SecurityToken> tokens; 106 bool canMatchLocalId; 107 SimpleTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId)108 public SimpleTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId) 109 { 110 if (tokens == null) 111 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokens"); 112 113 this.tokens = tokens; 114 this.canMatchLocalId = canMatchLocalId; 115 } 116 TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)117 protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) 118 { 119 if (keyIdentifierClause == null) 120 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 121 122 key = null; 123 for (int i = 0; i < this.tokens.Count; ++i) 124 { 125 SecurityKey securityKey = this.tokens[i].ResolveKeyIdentifierClause(keyIdentifierClause); 126 if (securityKey != null) 127 { 128 key = securityKey; 129 return true; 130 } 131 } 132 133 if (keyIdentifierClause is EncryptedKeyIdentifierClause) 134 { 135 EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause; 136 SecurityKeyIdentifier keyIdentifier = keyClause.EncryptingKeyIdentifier; 137 if (keyIdentifier != null && keyIdentifier.Count > 0) 138 { 139 for (int i = 0; i < keyIdentifier.Count; i++) 140 { 141 SecurityKey unwrappingSecurityKey = null; 142 if (TryResolveSecurityKey(keyIdentifier[i], out unwrappingSecurityKey)) 143 { 144 byte[] wrappedKey = keyClause.GetEncryptedKey(); 145 string wrappingAlgorithm = keyClause.EncryptionMethod; 146 byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey); 147 key = new InMemorySymmetricSecurityKey(unwrappedKey, false); 148 return true; 149 } 150 } 151 } 152 } 153 154 return key != null; 155 } 156 TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)157 protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token) 158 { 159 if (keyIdentifier == null) 160 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier"); 161 162 token = null; 163 for (int i = 0; i < keyIdentifier.Count; ++i) 164 { 165 166 SecurityToken securityToken = ResolveSecurityToken(keyIdentifier[i]); 167 if (securityToken != null) 168 { 169 token = securityToken; 170 break; 171 } 172 } 173 174 return (token != null); 175 } 176 TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)177 protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) 178 { 179 if (keyIdentifierClause == null) 180 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 181 182 token = null; 183 184 SecurityToken securityToken = ResolveSecurityToken(keyIdentifierClause); 185 if (securityToken != null) 186 token = securityToken; 187 188 return (token != null); 189 } 190 ResolveSecurityToken(SecurityKeyIdentifierClause keyIdentifierClause)191 SecurityToken ResolveSecurityToken(SecurityKeyIdentifierClause keyIdentifierClause) 192 { 193 if (keyIdentifierClause == null) 194 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause"); 195 196 if (!this.canMatchLocalId && keyIdentifierClause is LocalIdKeyIdentifierClause) 197 return null; 198 199 for (int i = 0; i < this.tokens.Count; ++i) 200 { 201 if (this.tokens[i].MatchesKeyIdentifierClause(keyIdentifierClause)) 202 return this.tokens[i]; 203 } 204 205 return null; 206 } 207 208 } 209 210 } 211 } 212