1 //------------------------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------------------------ 4 5 namespace System.ServiceModel.Configuration 6 { 7 using System; 8 using System.Collections.ObjectModel; 9 using System.ComponentModel; 10 using System.Configuration; 11 using System.IdentityModel.Tokens; 12 using System.IO; 13 using System.Runtime; 14 using System.ServiceModel; 15 using System.ServiceModel.Description; 16 using System.ServiceModel.Security.Tokens; 17 using System.Text; 18 using System.Xml; 19 20 public sealed partial class IssuedTokenParametersElement : ServiceModelConfigurationElement 21 { 22 Collection<IssuedTokenParametersElement> optionalIssuedTokenParameters = null; 23 IssuedTokenParametersElement()24 public IssuedTokenParametersElement() 25 { 26 } 27 28 [ConfigurationProperty(ConfigurationStrings.DefaultMessageSecurityVersion)] 29 [TypeConverter(typeof(MessageSecurityVersionConverter))] 30 public MessageSecurityVersion DefaultMessageSecurityVersion 31 { 32 get { return (MessageSecurityVersion)base[ConfigurationStrings.DefaultMessageSecurityVersion]; } 33 set { base[ConfigurationStrings.DefaultMessageSecurityVersion] = value; } 34 } 35 36 [ConfigurationProperty(ConfigurationStrings.AdditionalRequestParameters)] 37 public XmlElementElementCollection AdditionalRequestParameters 38 { 39 get { return (XmlElementElementCollection)base[ConfigurationStrings.AdditionalRequestParameters]; } 40 } 41 42 [ConfigurationProperty(ConfigurationStrings.ClaimTypeRequirements)] 43 public ClaimTypeElementCollection ClaimTypeRequirements 44 { 45 get { return (ClaimTypeElementCollection)base[ConfigurationStrings.ClaimTypeRequirements]; } 46 } 47 48 [ConfigurationProperty(ConfigurationStrings.Issuer)] 49 public IssuedTokenParametersEndpointAddressElement Issuer 50 { 51 get { return (IssuedTokenParametersEndpointAddressElement)base[ConfigurationStrings.Issuer]; } 52 } 53 54 [ConfigurationProperty(ConfigurationStrings.IssuerMetadata)] 55 public EndpointAddressElementBase IssuerMetadata 56 { 57 get { return (EndpointAddressElementBase)base[ConfigurationStrings.IssuerMetadata]; } 58 } 59 60 [ConfigurationProperty(ConfigurationStrings.KeySize, DefaultValue = 0)] 61 [IntegerValidator(MinValue = 0)] 62 public int KeySize 63 { 64 get { return (int)base[ConfigurationStrings.KeySize]; } 65 set { base[ConfigurationStrings.KeySize] = value; } 66 } 67 68 [ConfigurationProperty(ConfigurationStrings.KeyType, DefaultValue = IssuedSecurityTokenParameters.defaultKeyType)] 69 [ServiceModelEnumValidator(typeof(System.IdentityModel.Tokens.SecurityKeyTypeHelper))] 70 public SecurityKeyType KeyType 71 { 72 get { return (SecurityKeyType)base[ConfigurationStrings.KeyType]; } 73 set { base[ConfigurationStrings.KeyType] = value; } 74 } 75 76 internal Collection<IssuedTokenParametersElement> OptionalIssuedTokenParameters 77 { 78 get 79 { 80 // OptionalIssuedTokenParameters built on assumption that configuration is writable. 81 // This should be protected at the callers site. If assumption is invalid, then 82 // configuration system is in an indeterminate state. Need to stop in a manner that 83 // user code can not capture. 84 if (this.IsReadOnly()) 85 { 86 Fx.Assert("IssuedTokenParametersElement.OptionalIssuedTokenParameters should only be called by Admin APIs"); 87 DiagnosticUtility.FailFast("IssuedTokenParametersElement.OptionalIssuedTokenParameters should only be called by Admin APIs"); 88 } 89 90 // No need to worry about a race condition here-- this method is not meant to be called by multi-threaded 91 // apps. It is only supposed to be called by svcutil and single threaded equivalents. 92 if (this.optionalIssuedTokenParameters == null) 93 { 94 this.optionalIssuedTokenParameters = new Collection<IssuedTokenParametersElement>(); 95 } 96 return this.optionalIssuedTokenParameters; 97 } 98 } 99 100 101 [ConfigurationProperty(ConfigurationStrings.TokenType, DefaultValue = "")] 102 [StringValidator(MinLength = 0)] 103 public string TokenType 104 { 105 get { return (string)base[ConfigurationStrings.TokenType]; } 106 set 107 { 108 if (String.IsNullOrEmpty(value)) 109 { 110 value = String.Empty; 111 } 112 113 base[ConfigurationStrings.TokenType] = value; 114 } 115 } 116 117 [ConfigurationProperty(ConfigurationStrings.UseStrTransform, DefaultValue = false)] 118 public bool UseStrTransform 119 { 120 get { return (bool)base[ConfigurationStrings.UseStrTransform]; } 121 set { base[ConfigurationStrings.UseStrTransform] = value; } 122 } 123 ApplyConfiguration(IssuedSecurityTokenParameters parameters)124 internal void ApplyConfiguration(IssuedSecurityTokenParameters parameters) 125 { 126 if (parameters == null) 127 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters")); 128 129 if (this.AdditionalRequestParameters != null) 130 { 131 foreach (XmlElementElement e in this.AdditionalRequestParameters) 132 { 133 parameters.AdditionalRequestParameters.Add(e.XmlElement); 134 } 135 } 136 137 if (this.ClaimTypeRequirements != null) 138 { 139 foreach (ClaimTypeElement c in this.ClaimTypeRequirements) 140 { 141 parameters.ClaimTypeRequirements.Add(new ClaimTypeRequirement(c.ClaimType, c.IsOptional)); 142 } 143 } 144 145 parameters.KeySize = this.KeySize; 146 parameters.KeyType = this.KeyType; 147 parameters.DefaultMessageSecurityVersion = this.DefaultMessageSecurityVersion; 148 parameters.UseStrTransform = this.UseStrTransform; 149 150 if (!string.IsNullOrEmpty(this.TokenType)) 151 { 152 parameters.TokenType = this.TokenType; 153 } 154 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.Issuer].ValueOrigin) 155 { 156 this.Issuer.Validate(); 157 158 parameters.IssuerAddress = ConfigLoader.LoadEndpointAddress(this.Issuer); 159 160 if (!string.IsNullOrEmpty(this.Issuer.Binding)) 161 { 162 parameters.IssuerBinding = ConfigLoader.LookupBinding(this.Issuer.Binding, this.Issuer.BindingConfiguration, this.EvaluationContext); 163 } 164 } 165 166 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.IssuerMetadata].ValueOrigin) 167 { 168 parameters.IssuerMetadataAddress = ConfigLoader.LoadEndpointAddress(this.IssuerMetadata); 169 } 170 } 171 Copy(IssuedTokenParametersElement source)172 internal void Copy(IssuedTokenParametersElement source) 173 { 174 if (this.IsReadOnly()) 175 { 176 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigReadOnly))); 177 } 178 if (null == source) 179 { 180 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("source"); 181 } 182 183 foreach (XmlElementElement xmlElement in source.AdditionalRequestParameters) 184 { 185 XmlElementElement newElement = new XmlElementElement(); 186 newElement.Copy(xmlElement); 187 this.AdditionalRequestParameters.Add(newElement); 188 } 189 190 foreach (ClaimTypeElement c in source.ClaimTypeRequirements) 191 { 192 this.ClaimTypeRequirements.Add(new ClaimTypeElement(c.ClaimType, c.IsOptional)); 193 } 194 195 this.KeySize = source.KeySize; 196 this.KeyType = source.KeyType; 197 this.TokenType = source.TokenType; 198 this.DefaultMessageSecurityVersion = source.DefaultMessageSecurityVersion; 199 this.UseStrTransform = source.UseStrTransform; 200 201 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.Issuer].ValueOrigin) 202 { 203 this.Issuer.Copy(source.Issuer); 204 } 205 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.IssuerMetadata].ValueOrigin) 206 { 207 this.IssuerMetadata.Copy(source.IssuerMetadata); 208 } 209 } 210 Create(bool createTemplateOnly, SecurityKeyType templateKeyType)211 internal IssuedSecurityTokenParameters Create(bool createTemplateOnly, SecurityKeyType templateKeyType) 212 { 213 IssuedSecurityTokenParameters result = new IssuedSecurityTokenParameters(); 214 if (!createTemplateOnly) 215 { 216 this.ApplyConfiguration(result); 217 } 218 else 219 { 220 result.KeyType = templateKeyType; 221 } 222 return result; 223 } 224 InitializeFrom(IssuedSecurityTokenParameters source, bool initializeNestedBindings)225 internal void InitializeFrom(IssuedSecurityTokenParameters source, bool initializeNestedBindings) 226 { 227 if (null == source) 228 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("source"); 229 230 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.KeyType, source.KeyType); 231 if (source.KeySize > 0) 232 { 233 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.KeySize, source.KeySize); 234 } 235 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.TokenType, source.TokenType); 236 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.UseStrTransform, source.UseStrTransform); 237 238 if (source.IssuerAddress != null) 239 this.Issuer.InitializeFrom(source.IssuerAddress); 240 241 if (source.DefaultMessageSecurityVersion != null) 242 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.DefaultMessageSecurityVersion, source.DefaultMessageSecurityVersion); 243 244 if (source.IssuerBinding != null && initializeNestedBindings) 245 { 246 this.Issuer.BindingConfiguration = this.Issuer.Address.ToString(); 247 string bindingSectionName; 248 BindingsSection.TryAdd(this.Issuer.BindingConfiguration, 249 source.IssuerBinding, 250 out bindingSectionName); 251 this.Issuer.Binding = bindingSectionName; 252 } 253 254 if (source.IssuerMetadataAddress != null) 255 { 256 this.IssuerMetadata.InitializeFrom(source.IssuerMetadataAddress); 257 } 258 259 foreach (XmlElement element in source.AdditionalRequestParameters) 260 { 261 this.AdditionalRequestParameters.Add(new XmlElementElement(element)); 262 } 263 264 foreach (ClaimTypeRequirement c in source.ClaimTypeRequirements) 265 { 266 this.ClaimTypeRequirements.Add(new ClaimTypeElement(c.ClaimType, c.IsOptional)); 267 } 268 269 foreach (IssuedSecurityTokenParameters.AlternativeIssuerEndpoint alternativeIssuer in source.AlternativeIssuerEndpoints) 270 { 271 IssuedTokenParametersElement element = new IssuedTokenParametersElement(); 272 element.Issuer.InitializeFrom(alternativeIssuer.IssuerAddress); 273 if (initializeNestedBindings) 274 { 275 element.Issuer.BindingConfiguration = element.Issuer.Address.ToString(); 276 string bindingSectionName; 277 BindingsSection.TryAdd(element.Issuer.BindingConfiguration, 278 alternativeIssuer.IssuerBinding, 279 out bindingSectionName); 280 element.Issuer.Binding = bindingSectionName; 281 } 282 this.OptionalIssuedTokenParameters.Add(element); 283 } 284 } 285 SerializeToXmlElement(XmlWriter writer, String elementName)286 protected override bool SerializeToXmlElement(XmlWriter writer, String elementName) 287 { 288 bool writeMe = base.SerializeToXmlElement(writer, elementName); 289 bool writeComment = this.OptionalIssuedTokenParameters.Count > 0; 290 if (writeComment && writer != null) 291 { 292 MemoryStream memoryStream = new MemoryStream(); 293 using (XmlTextWriter commentWriter = new XmlTextWriter(memoryStream, Encoding.UTF8)) 294 { 295 commentWriter.Formatting = Formatting.Indented; 296 commentWriter.WriteStartElement(ConfigurationStrings.AlternativeIssuedTokenParameters); 297 foreach (IssuedTokenParametersElement element in this.OptionalIssuedTokenParameters) 298 { 299 element.SerializeToXmlElement(commentWriter, ConfigurationStrings.IssuedTokenParameters); 300 } 301 commentWriter.WriteEndElement(); 302 commentWriter.Flush(); 303 string commentString = new UTF8Encoding().GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); 304 writer.WriteComment(commentString.Substring(1, commentString.Length - 1)); 305 commentWriter.Close(); 306 } 307 } 308 return writeMe || writeComment; 309 } 310 Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)311 protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode) 312 { 313 if (sourceElement is IssuedTokenParametersElement) 314 { 315 IssuedTokenParametersElement source = (IssuedTokenParametersElement)sourceElement; 316 this.optionalIssuedTokenParameters = source.optionalIssuedTokenParameters; 317 } 318 319 base.Unmerge(sourceElement, parentElement, saveMode); 320 } 321 } 322 } 323 324 325 326