微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么AuthorizationOptions不使用ConcurrentDictionary

如何解决为什么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 举报,一经查实,本站将立刻删除。