繁体   English   中英

在.NET Core Web应用程序中存储Identity Server的访问令牌

[英]Storing access token from Identity Server in NET Core web application

我有针对API的网络核心Web应用程序,并使用Identity Server(也作为Web应用程序)进行身份验证。 因为应用程序是基于Web服务器的,所以我存在从Identity Server存储访问令牌的问题,该应用程序需要在每个请求(在Header中)以便与API通信。 一个理想的流程是:用户启动应用程序并提示输入他的电话号码(以获取OTP代码并进行身份验证),当提交电话号码时,Identity Server与某些外部提供商向用户发送OTP代码,现在用户正在提示输入OTP代码。 成功提交OTP代码后,Identity Server会对其进行验证并向客户端提供访问令牌。 这就是问题开始的关键所在。

首先,我尝试使用单件存储访问令牌,在otp验证后存储(在某些字典中)访问与电话号码相关的令牌作为密钥。 但是,问题是因为应用程序是基于Web服务器的,并且在服务器上的生产中并不是每个用户都必须在服务器上运行他的应用程序实例,所以单例是无用的,因为我们在示例3-4应用程序运行20个用户并且在那种情况下,不止一个用户使用相同的单身人士! 然后我用谷歌搜索,发现最好的选择是在浏览器会话或文档cookie中存储访问令牌或该令牌的一些实际密钥。 所以现在应用程序的工作方式是,在OTP代码验证后,用户的电话号码和访问令牌存储在Dictionary集合中(现在更多的用户使用相同的集合,因为单身对此没用),其中密钥是电话号码,访问令牌是值,然后javascript触发并在cookie中设置用户电话号码(在每个请求中),现在在创建Bearer标题时,我只需从当前请求中读取cookie,并使用该电话号码从集合中获取访问令牌。 所以这个解决方案非常糟糕,因为您需要获取访问令牌的所有内容(登录后)都是修改cookie中的电话号码,如果您很幸运并且匹配集合中的某些现有号码,您将获得访问令牌并轻松访问API 。

下面是在每个请求中调用的方法,以便从集合中获取访问令牌,其中在otp验证之后放置具有电话号码的访问令牌。

public async Task<string> GetAccessToken()
        {
            string phoneNumber = GetUserPhoneNumber();

            if (string.IsNullOrEmpty(phoneNumber))
                throw new ArgumentNullException(nameof(phoneNumber));

            if (_usersTokenStore == null || _usersTokenStore.Count == 0)
                throw new NotImplementedException(nameof(_usersTokenStore));

            var refSingleUser = new SingleUserTokenStore();
            bool userHaveAccessToken = _usersTokenStore.TryGetValue(phoneNumber, out refSingleUser);

            if (!userHaveAccessToken)
                throw new Exception($"User with {phoneNumber} not authorized.");

            if (refSingleUser.IsTimeToRefreshToken)
               return await RefreshAndGetAccessToken();

            return refSingleUser.AccessToken;
        }


private string GetUserPhoneNumber()
        {
            if (_httpContext == null)
                throw new ArgumentException(nameof(_httpContext));

            var phoneNumberCookie = _httpContext.HttpContext.Request.Cookies.Where(c => c.Key == "phone_number").FirstOrDefault();

            if (phoneNumberCookie.Value == null || phoneNumberCookie.Key == null)
                return null;

            return phoneNumberCookie.Value;
        }

目前还不清楚你在这里做什么。 如果这是一个Web应用程序(即向用户显示他们在Web浏览器中导航的HTML视图),那么您需要使用cookie身份验证。 Web浏览器的用户无法为每个请求传递Authorization标头。 Cookie auth是在Web浏览器中持久身份验证的唯一方法。

如果这是一个API,则客户端将存储访问令牌,并通过Authorization标头将其与每个请求一起提交。

在任何一种情况下,您都不应该持久化auth令牌服务器端。 这不是服务器的责任。

暂无
暂无

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

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