.NET自定义ConfigurationSection嵌套集合报未识别audience错误
问题原因
- 核心问题是C#代码定义的配置层级和web.config实际结构不匹配:你在
MultipleCertAuthorisationConfigurationSection中声明的名为it2.jwtAuthorisation的ConfigurationProperty是集合容器节点,且通过ConfigurationCollection特性指定该集合的添加项节点名为add,按照.NET配置系统的规则,这类AddRemoveClearMap类型的集合下仅识别<add>、<clear>、<remove>三种子节点。但你在web.config中直接将单个授权配置的子节点(<audience>、<issuer>等)写在了集合容器下,没有用<add>节点包裹单个配置实例,导致解析器读到<audience>时判定为未识别元素,抛出异常。 - 隐藏缺陷1:当前
JWTAuthorisationCollection的集合类型为AddRemoveClearMap,该模式不支持自定义集合项的节点名,无法直接使用it2.jwtAuthorisation作为单个配置项的标签。 - 隐藏缺陷2:
JWTAuthorisationCollection.GetElementKey方法直接返回了Issuer这个ConfigurationElement实例,而非issuer节点上的iss字符串属性值,后续集合去重、索引查询会抛出类型不匹配错误。 - 隐藏缺陷3:如果嵌套的
AudienceProviderElement、IssuerProviderElement、证书引用集合类没有正确给属性标记ConfigurationProperty特性,后续解析节点属性时会触发新的解析错误。
修复方案
根据你想要的配置结构二选一即可:
方案1:仅修改web.config,适配现有C#代码
无需调整C#类,只需要在集合容器节点<it2.jwtAuthorisation>下用<add>标签包裹每个授权配置实例,修改后的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <configSections> <section name="it2.AuthorisationSchemes" type="WebAPI.Authentication.Configuration.JWT.MultipleCertAuthorisationConfigurationSection, WebAPI, Version=1.0.0.0, Culture=neutral" /> </configSections> <it2.AuthorisationSchemes> <it2.jwtAuthorisation> <!-- 每个<add>对应一个JWT授权实例,多实例直接新增<add>节点即可 --> <add> <audience aud="https://localhost" /> <issuer iss="IT2" /> <certificateSigningKeys> <certificateReference x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" findValue="IT2.AccessTokenSigningKey" /> </certificateSigningKeys> </add> </it2.jwtAuthorisation> </it2.AuthorisationSchemes> </configuration>
方案2:调整C#代码,适配你预期的配置结构
如果你需要保持原web.config结构(<it2.AuthorisationSchemes>下直接放置多个<it2.jwtAuthorisation>节点作为配置实例,无<add>和额外包裹层),按以下步骤修改代码:
- 修改
MultipleCertAuthorisationConfigurationSection,将授权集合标记为配置节的默认集合,指定集合项的节点名为it2.jwtAuthorisation:
public class MultipleCertAuthorisationConfigurationSection : ConfigurationSection { [ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)] [ConfigurationCollection(typeof(JWTAuthorisationCollection), AddItemName = "it2.jwtAuthorisation", ClearItemsName = "clear", RemoveItemName = "remove")] public JWTAuthorisationCollection JwtAuthSchemes { get => (JWTAuthorisationCollection)base[""]; set => base[""] = value; } }
- 修改
JWTAuthorisationCollection,将集合类型改为支持自定义子节点名的BasicMap,重写节点名属性,同时修复集合键取值逻辑:
public class JWTAuthorisationCollection : ConfigurationElementCollection { public override ConfigurationElementCollectionType CollectionType { get => ConfigurationElementCollectionType.BasicMap; } protected override string ElementName => "it2.jwtAuthorisation"; protected override ConfigurationElement CreateNewElement() { return new JWTAuthorisationElement(); } protected override object GetElementKey(ConfigurationElement element) { // 注意:Iss需替换为你IssuerProviderElement类中对应iss属性的实际C#属性名 return ((JWTAuthorisationElement)element).Issuer.Iss; } // 原有索引、增删方法(this[int]、Add、Remove、Clear等)无需修改 }
- 校验所有嵌套配置类的特性标记:
AudienceProviderElement中必须定义对应aud属性的C#属性,标记[ConfigurationProperty("aud", IsRequired = true)]IssuerProviderElement中必须定义对应iss属性的C#属性,标记[ConfigurationProperty("iss", IsKey = true, IsRequired = true)]MultipleCertReferenceSigningKeyProviderElements证书集合需同样设置CollectionType为BasicMap,重写ElementName返回certificateReference,确保证书节点可被正常解析。
修改完成后,你最初编写的web.config结构即可正常加载,支持配置多个<it2.jwtAuthorisation>实例。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

