为什么AuthorizationOptions不使用ConcurrentDictionary

问题描述

最近,我的AuthorizationPolicyProvider类偶尔遇到错误

 <div className="user form">
       <h2>User</h2>
       <span>Username</span>
       <input type="text" placeholder="Username" name="uname" onChange={userForm} id="" />
       <span>Password</span>
       <input type="password" name="pwd" id="" placeholder="Password" onChange={userForm} />
       <span>Confirm Password</span>
       <input type="password" name="cpwd" id="" placeholder="Confirm Password " onChange{userForm} />
       <Link to="/" ><button>Resigister</button></Link>
   </div>
   <Switch>
          <Route exact path="/">
                <Mycontext.Provider value={form}>
                    <Login />
                </Mycontext.Provider>
          </Route>
            <Route path="/a" component={Admin} />
        </Switch>

以下是一些错误堆栈:

public class AuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
{
    private readonly Authorizationoptions options;

    public AuthorizationPolicyProvider(IOptions<Authorizationoptions> options)
        : base(options)
    {
        this.options = options.Value;
    }

    /// this method is supposed to be the place where the error arises
    public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        AuthorizationPolicy policy = await base.GetPolicyAsync(policyName);

        if (policy == null)
        {
            policy = new AuthorizationPolicyBuilder()
                            .AddRequirements(new PermissionRequirement(policyName))
                            .Build();
            this.options.AddPolicy(policyName,policy);
        }

        return policy;
    }
}

基于错误堆栈,我猜测该错误可能是由于Dictionary的多线程问题引起的,因为Authorizationoptions的实现使用Dictionary而不是ConcurrentDictionary:

    System.NullReferenceException:
   at System.Collections.Generic.Dictionary`2.TryInsert (System.Private.CoreLib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=7cec85d7bea7798e)
   at System.Collections.Generic.Dictionary`2.set_Item (System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e)
   at Microsoft.AspNetCore.Authorization.Authorizationoptions.AddPolicy (Microsoft.AspNetCore.Authorization,Version=3.1.6.0,PublicKeyToken=adb9793829ddae60)
.....

然后在link中遵循Microsoft的指南,并将自定义AuthorizationPolicyProvider添加为Singleton:

namespace Microsoft.AspNetCore.Authorization
{
    /// <summary>
    /// Provides programmatic configuration used by <see cref="IAuthorizationService"/> and <see cref="IAuthorizationPolicyProvider"/>.
    /// </summary>
    public class Authorizationoptions
    {
        // Why dont they use ConcurrentDictionary here
        private IDictionary<string,AuthorizationPolicy> PolicyMap { get; } = new Dictionary<string,AuthorizationPolicy>(StringComparer.OrdinalIgnoreCase);
....
        public AuthorizationPolicy GetPolicy(string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            return PolicyMap.ContainsKey(name) ? PolicyMap[name] : null;
        }
    }
}

所以你们知道他们为什么不使用ConcurrentDictionary,是Microsoft的bug,还是因为我的实现,谢谢您。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)