使用 ADFS 3.0、ADAL、Web API 和 Xamarin 刷新令牌

Refresh tokens with ADFS 3.0, ADAL, Web API, and Xamarin

我们在使刷新令牌正常工作时遇到问题。最初,用户使用来自 ADAL 的 Web 视图登录并获取令牌。该令牌用于调用 Web API 直到它过期。我们没有像预期的那样在没有网络提示的情况下获取新令牌,而是在服务器上记录了一个错误,并再次向用户显示登录网络提示。

根据我们的阅读,您应该在每次调用时使用 AcquireTokenAsync 并让 ADAL 处理 tokens/refresh 令牌。

这是当 ADAL 尝试使用刷新令牌获取新令牌时我们在服务器上遇到的错误。我们已尝试搜索该错误,但没有找到多少。

Encountered error during OAuth token request.

Additional Data

Exception details: Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthInvalidScopeException: MSIS9330: The OAuth access token request received is invalid. A 'scope' parameter was received in the request and AD FS does not support any scope. Received scope: 'openid'. at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthToken.OAuthRefreshTokenRequestContext.Validate()

我们是不是漏掉了什么?有没有办法设置范围,或者这不适用于我们正在使用的当前版本? ADAL 是使 post 具有 ADFS 服务器范围的那个。

我们没有使用 Azure AD!

来自 iOS 应用中视图控制器的调用:

PlatformParameters p = new PlatformParameters(this);

AuthenticationContext authContext = new AuthenticationContext("https://adfs.domain.com/adfs", false);

AuthenticationResult _authResult = await authContext.AcquireTokenAsync("https://webapi.domain.com", "E1CF1107-FF90-4228-93BF-26052DD2C714", “http://anarbitraryreturnuri/”, p);

Startup.Auth.cs 网络 API:

public void ConfigureAuth(IAppBuilder app)
        {
            app.UseActiveDirectoryFederationServicesBearerAuthentication(
                new ActiveDirectoryFederationServicesBearerAuthenticationOptions
                {
                    MetadataEndpoint = ConfigurationManager.AppSettings["ida:AdfsMetadataEndpoint"],
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidAudience = ConfigurationManager.AppSettings["ida:Audience"],
                    },
                }
        }

以下是我们的作品:

以下是我们用来实现此功能的一些 post:

http://www.cloudidentity.com/blog/2013/10/25/securing-a-web-api-with-adfs-on-ws2012-r2-got-even-easier/

http://www.cloudidentity.com/blog/2015/08/13/adal-3-didnt-return-refresh-tokens-for-5-months-and-nobody-noticed/

问题出在 ADAL 源代码中。服务器日志中的错误非常具体:

请求中收到了 'scope' 参数,AD FS 不支持任何范围。接收范围:'openid'。 ADAL 库在尝试获取刷新令牌时发送范围参数。 ADFS 3.0 不支持 openid 范围,因此失败。

从 github 下载 ADAL 代码 -- https://github.com/AzureAD/azure-activedirectory-library-for-dotnet

打开位于此处的 AcquireTokenHandlerBase.cs:

从 SendTokenRequestByRefreshTokenAsync 调用中删除范围:

protected async Task<AuthenticationResultEx> SendTokenRequestByRefreshTokenAsync(string refreshToken)
    {
        var requestParameters = new DictionaryRequestParameters(this.Resource, this.ClientKey);
        requestParameters[OAuthParameter.GrantType] = OAuthGrantType.RefreshToken;
        requestParameters[OAuthParameter.RefreshToken] = refreshToken;
        //requestParameters[OAuthParameter.Scope] = OAuthValue.ScopeOpenId; **This line causes refresh to fail**

        AuthenticationResultEx result = await this.SendHttpMessageAsync(requestParameters).ConfigureAwait(false);

        if (result.RefreshToken == null)
        {
            result.RefreshToken = refreshToken;
            PlatformPlugin.Logger.Verbose(this.CallState,
                "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead");
        }

        return result;
    }

清理并重建项目。用新的 DLL 替换 nuget 引用。确保在 Xamarin iOS 项目中包含平台 DLL。

现在,当 ADAL 尝试获取刷新令牌时,它应该会成功。