2017-02-13 4 views
1

Nous avons des problèmes pour faire fonctionner les jetons d'actualisation. Initialement, l'utilisateur se connecte en utilisant la vue web d'ADAL et obtient un jeton. Ce jeton est utilisé pour appeler l'API Web jusqu'à son expiration. Au lieu d'obtenir un nouveau jeton sans l'invite Web comme nous l'attendions, une erreur est enregistrée sur le serveur et l'utilisateur reçoit de nouveau l'invite Web de connexion. D'après ce que nous avons lu, vous devez utiliser AcquireTokenAsync à chaque appel et laisser ADAL gérer les jetons/rafraîchir les jetons.Actualiser les jetons avec ADFS 3.0, ADAL, Web API et Xamarin

Voici l'erreur que nous obtenons sur le serveur lorsque ADAL essaie d'obtenir un nouveau jeton en utilisant le jeton d'actualisation. Nous avons essayé de chercher cette erreur mais nous n'en trouvons pas beaucoup.

Erreur rencontrée lors de la demande de jeton OAuth.

données

détails de l'exception: Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthInvalidScopeException: MSIS9330: La demande de jeton d'accès OAuth reçu est invalide. Un paramètre 'scope' a été reçu dans la demande et AD FS ne prend pas en charge les portées . Portée reçue: 'openid'. à Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthToken.OAuthRefreshTokenRequestContext.Validate()

Sommes-nous manque quelque chose? Existe-t-il un moyen de définir la portée ou cela ne fonctionne-t-il pas avec les versions actuelles que nous utilisons? ADAL est celui qui fait la publication avec la portée du serveur ADFS.

Nous n'utilisons pas Azure AD!

L'appel du contrôleur de vue dans l'application 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 dans l'API Web:

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

Voici les pièces que nous avons:

  • Windows Server 2012 R2 avec ADFS 3.0 (sur site)
  • SsoLifetime = 60
  • TokenLifetime (parti comptant) = 10
  • ADAL 3.13.8
  • .NET API Web
  • Xamarin iOS app

Voici quelques-uns des messages que nous avons utilisé pour obtenir ce travail:

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/

Répondre

1

Le problème est dans le code source ADAL. L'erreur du journal du serveur était assez spécifique:

Un paramètre 'scope' a été reçu dans la requête et AD FS ne prend en charge aucune portée.Portée reçue: 'openid'. La bibliothèque ADAL envoie un paramètre scope quand il essaie d'obtenir un jeton d'actualisation. ADFS 3.0 ne prend pas en charge la portée openid de sorte qu'il échoue.

Téléchargez le code ADAL de github - https://github.com/AzureAD/azure-activedirectory-library-for-dotnet

Ouvert AcquireTokenHandlerBase.cs situé ici:

enter image description here

Retirez la portée de l'appel 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; 
    } 

propre et reconstruire les projets. Remplacez les références de nuget avec les nouvelles DLL. Assurez-vous d'inclure la DLL de la plateforme dans le projet Xamarin iOS.

enter image description here

Maintenant, quand ADAL tente d'obtenir un rafraîchissement jeton, il doit réussir.

enter image description here