简体   繁体   English

如何使用包含自定义“元素”的嵌套“ConfigurationElementCollection”实现自定义“ConfigurationSection”

[英]How to implement a custom "ConfigurationSection" with a nested "ConfigurationElementCollection" containing a custom "Element"

I am trying to implement a custom configuration section containing a collection of another custom element.我正在尝试实现一个自定义配置部分,其中包含另一个自定义元素的集合。 The customer element contains some simple strings but also a collection of certificateReference. customer 元素包含一些简单的字符串,但也包含证书引用的集合。

I have only included one instance of <it2.jwtAuthorisation> for now in the web.config, but this should be able to have multiple.我现在只在 web.config 中包含了一个 <it2.jwtAuthorisation> 实例,但这应该可以有多个。

The issue I'm having is when loading the configuration I get the following error:我遇到的问题是在加载配置时出现以下错误:

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" />

I have tried changing the classes several times but without any luck.我曾多次尝试更改课程,但没有任何运气。

This is the web.config file这是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>

This is the MultipleCertAuthorisationConfigurationSection definition:这是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;
      }
    }
  }

This is the JWTAuthorisationCollection definition:这是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();
    }
  }

This is the JWTAuthorisationElement definition:这是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;
      }
    }
  }

It gets loaded by the following function and this is where the error occurs:它由以下函数加载,这是发生错误的地方:

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

I managed to solve this after finding Correct implementation of a custom config section with nested collections?在找到具有嵌套集合的自定义配置部分的正确实现后,我设法解决了这个问题? . . The Answer was exactly what I was looking for and the linked blog post gave a detailed description with the code on how to do this.答案正是我想要的,链接的博客文章详细描述了如何执行此操作的代码。

It seems like another person in the comments had the same issue following the Microsoft example:在 Microsoft 示例之后,评论中的另一个人似乎也遇到了同样的问题:

The key for me here was setting CollectionType on the nested collection to ConfigurationElementCollectionType.BasicMap.对我来说,这里的关键是将嵌套集合上的 CollectionType 设置为 ConfigurationElementCollectionType.BasicMap。 Without it I kept getting Unrecognized element 'tunnel'没有它,我不断收到无法识别的元素“隧道”

This was also the error I was receiving.这也是我收到的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM