使用 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"],
},
}
}
以下是我们的作品:
- Windows Server 2012 R2 with ADFS 3.0(本地)
- SsoLifetime = 60
- TokenLifetime(依赖方)= 10
- ADAL 3.13.8
- .NET 网站 API
- Xamarin iOS 应用
以下是我们用来实现此功能的一些 post:
问题出在 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 尝试获取刷新令牌时,它应该会成功。
我们在使刷新令牌正常工作时遇到问题。最初,用户使用来自 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"],
},
}
}
以下是我们的作品:
- Windows Server 2012 R2 with ADFS 3.0(本地)
- SsoLifetime = 60
- TokenLifetime(依赖方)= 10
- ADAL 3.13.8
- .NET 网站 API
- Xamarin iOS 应用
以下是我们用来实现此功能的一些 post:
问题出在 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 尝试获取刷新令牌时,它应该会成功。