【问题标题】:How to implement a custom ConfigurationSection with a nested ConfigurationElementCollection containing a custom Element如何使用包含自定义元素的嵌套 ConfigurationElementCollection 实现自定义 ConfigurationSection
【发布时间】:2022-06-10 22:35:54
【问题描述】:

我正在尝试实现一个自定义配置部分,其中包含另一个自定义元素的集合。 customer 元素包含一些简单的字符串,但也包含一个 certificateReference 集合。

我现在只在 web.config 中包含了一个 的实例,但这应该可以有多个。

我遇到的问题是在加载配置时出现以下错误:

Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request.

Parser Error Message: Unrecognized element 'audience'.

Source Error:

Line 15:   <it2.AuthorisationSchemes>
Line 16:     <it2.jwtAuthorisation>
Line 17:       <audience aud="https://localhost" />

我曾多次尝试更改课程,但没有任何运气。

这是 web.config 文件

<?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>
            <audience aud="https://localhost" />
            <issuer iss="IT2" />
            <certificateSigningKeys>
                <certificateReference x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" findValue="IT2.AccessTokenSigningKey" />
            </certificateSigningKeys>
        </it2.jwtAuthorisation>
    </it2.AuthorisationSchemes>
</configuration>

这是 MultipleCertAuthorisationConfigurationSection 定义:

public class MultipleCertAuthorisationConfigurationSection : ConfigurationSection
  {
    private const string authSchemes = "it2.jwtAuthorisation";
    [ConfigurationProperty(authSchemes, IsRequired = true)]
    [ConfigurationCollection(typeof(JWTAuthorisationCollection),
        AddItemName = "add",
        ClearItemsName = "clear",
        RemoveItemName = "remove")]
    public JWTAuthorisationCollection jwtAuthSchemes
    {
      get
      {
        JWTAuthorisationCollection jwtAuthorisationCollection =
    (JWTAuthorisationCollection)base[authSchemes];

        return jwtAuthorisationCollection;
      }
      set
      {
        JWTAuthorisationCollection jwtAuthorisationCollection = value;
      }
    }
  }

这是 JWTAuthorisationCollection 定义:

  public class JWTAuthorisationCollection : ConfigurationElementCollection
  {
    public JWTAuthorisationCollection()
    {
    }

    public override ConfigurationElementCollectionType CollectionType
    {
      get
      {
        return ConfigurationElementCollectionType.AddRemoveClearMap;
      }
    }

    protected override ConfigurationElement CreateNewElement()
    {
      return new JWTAuthorisationElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
      return ((JWTAuthorisationElement)element).Issuer;
    }

    public JWTAuthorisationElement this[int index]
    {
      get
      {
        return (JWTAuthorisationElement)BaseGet(index);
      }
      set
      {
        if (BaseGet(index) != null)
        {
          BaseRemoveAt(index);
        }
        BaseAdd(index, value);
      }
    }

    new public JWTAuthorisationElement this[string Issuer]
    {
      get
      {
        return (JWTAuthorisationElement)BaseGet(Issuer);
      }
    }

    public int IndexOf(JWTAuthorisationElement jwtAuth)
    {
      return BaseIndexOf(jwtAuth);
    }

    public void Add(JWTAuthorisationElement jwtAuth)
    {
      BaseAdd(jwtAuth);
    }

    protected override void BaseAdd(ConfigurationElement element)
    {
      BaseAdd(element, false);
    }

    public void Remove(JWTAuthorisationElement jwtAuth)
    {
      if (BaseIndexOf(jwtAuth) >= 0)
      {
        BaseRemove(jwtAuth.Issuer);
      }
    }

    public void RemoveAt(int index)
    {
      BaseRemoveAt(index);
    }

    public void Remove(string issuer)
    {
      BaseRemove(issuer);
    }

    public void Clear()
    {
      BaseClear();
    }
  }

这是 JWTAuthorisationElement 定义:

public class JWTAuthorisationElement : ConfigurationElement
  {
    public JWTAuthorisationElement(AudienceProviderElement audience, IssuerProviderElement issuer,
      JWKSEndpointProviderElement jwksEndpoint, MultipleCertReferenceSigningKeyProviderElements certificateSigningKeys, AppSecretSigningKeyProviderElement appSecretSigningKey)
    {
      Audience = audience;
      Issuer = issuer;
      JWKSEndpoint = jwksEndpoint;
      CertificateSigningKeys = certificateSigningKeys;
      AppSecretSigningKey = appSecretSigningKey;
    }

    public JWTAuthorisationElement()
    {
    }

    private const string audience = "audience";
    [ConfigurationProperty(audience, IsRequired = true)]
    public AudienceProviderElement Audience
    {
      get
      {
        return this[audience] as AudienceProviderElement;
      }
      set
      {
        this[audience] = value;
      }
    }

    private const string issuer = "issuer";
    [ConfigurationProperty(issuer, IsKey = true, IsRequired = true)]
    public IssuerProviderElement Issuer
    {
      get
      {
        return this[issuer] as IssuerProviderElement;
      }
      set
      {
        this[issuer] = value;
      }
    }

    private const string jwksEndpoint = "JWKSEndpoint";
    [ConfigurationProperty(jwksEndpoint, IsRequired = false)]
    public JWKSEndpointProviderElement JWKSEndpoint
    {
      get
      {
        return this[jwksEndpoint] as JWKSEndpointProviderElement;
      }
      set
      {
        this[jwksEndpoint] = value;
      }
    }

    private const string certificateSigningKeys = "certificateSigningKeys";
    [ConfigurationProperty(certificateSigningKeys, IsRequired = false)]
    [ConfigurationCollection(typeof(MultipleCertReferenceSigningKeyProviderElements), AddItemName = "certificateReference")]
    public MultipleCertReferenceSigningKeyProviderElements CertificateSigningKeys
    {
      get
      {
        return this[certificateSigningKeys] as MultipleCertReferenceSigningKeyProviderElements;
      }
      set
      {
        this[certificateSigningKeys] = value;
      }
    }

    private const string appSecretSigningKey = "appSecretSigningKey";
    [ConfigurationProperty(appSecretSigningKey, IsRequired = false)]
    public AppSecretSigningKeyProviderElement AppSecretSigningKey
    {
      get
      {
        return this[appSecretSigningKey] as AppSecretSigningKeyProviderElement;
      }
      set
      {
        this[appSecretSigningKey] = value;
      }
    }
  }

它由以下函数加载,这是发生错误的地方:

public AuthorisationConfigurationFactory()
  : this(System.Configuration.ConfigurationManager.GetSection("it2.AuthorisationSchemes") as JWT.MultipleCertAuthorisationConfigurationSection)
{
}

【问题讨论】:

    标签: c# xml configuration web-config configuration-files


    【解决方案1】:

    在找到Correct implementation of a custom config section with nested collections? 后,我设法解决了这个问题。答案正是我想要的,链接的博客文章详细描述了如何执行此操作的代码。

    似乎 cmets 中的另一个人在 Microsoft 示例之后遇到了同样的问题:

    对我来说这里的关键是在嵌套上设置 CollectionType 集合到 ConfigurationElementCollectionType.BasicMap。没有它 我不断收到无法识别的元素“隧道”

    这也是我收到的错误。

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 2010-11-13
      • 1970-01-01
      • 2019-05-08
      • 2011-07-31
      • 2014-10-08
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      相关资源
      最近更新 更多