Concurrent UserAccessCache

This pull request improves concurrent access to the `UserAccessCache` instance by removing the exclusive locks in favor of `ConcurrentDictionary` and `Lazy<T>`.

This pull request preserves the following behavior of the original code. This behavior is potentially unintended/unwanted but I figured I'm not in the correct place to make that determination.

When `forceCacheRefresh` is false *and* `refreshCallback` is null *and* the existing `UserAccess` instance is non-null and no longer valid (`userAccess.Token` is null or `IsExpired()` returns true), the function removes the value from the cache but instead of returning `null` it returns the existing value which was removed. The desired behavior may be to instead return null since the value was removed.