Skip to content
This repository has been archived by the owner on Jun 30, 2023. It is now read-only.

ADAL .NET Q & A

Bogdan Gavril edited this page Aug 11, 2022 · 10 revisions

The Scope of ADAL

What is the main functionality of ADAL?

Acquiring token from a Security Token Service (STS) for a client application.

What is ADAL .NET?

ADAL is available for many programming languages and platforms. ADAL .NET is a library which is based on .NET platforms and can be used in any application that supports .NET libraries.

What platforms does each version of ADAL .NET support?

ADAL .NET v1.0 only supports Windows desktop applications. ADAL .NET 2.x supports desktop applications, Windows 8 store, Windows Phone 8.1 store, .NET Core CLR and Windows Phone 8.1 Silverlight. ADAL .NET v3 supports all the platforms supported by ADAL 2.x except Silverlight. It also supports Xamarin and Xamarin Forms for developing iOS and Android applications.

What standard protocols does ADAL follow for token acquisition?

ADAL is implementing a custom version of the OAuth2 protocol. Also, for some specific scenarios, it may internally use other protocols (e.g. WS-Trust).

Is ADAL a general library for token acquisition using OAuth2 protocol?

No. ADAL is a client library for Azure Active Directory (AAD) and Active Directory Federation Services (ADFS). There are some custom notions such as “resource” required by ADAL which are considered extensions to the general OAuth2 protocol spec and not supported by other STS’s.

What STS’s does each version of ADAL support?

ADAL .NET v1.0 supports ACS (Access Control Service) and basic functionality of AAD. ADAL .NET 2.x and 3.x support AAD and ADFS 3.0, but note that ADFS does not offer all the functionality of AAD, so ADAL support for ADFS is currently limited to interactive scenarios for public (native) clients. ADAL also supports federation between AAD and ADFS which enables AAD login for ADFS users and Windows Integrated Authentication (WIA) for AAD via ADFS.

API Ramp Up

What is AuthenticationContext?

AuthenticationContext is the main class for ADAL with all the APIs needed for token acquisition from STS. It also stores some state between calls which reduces the need to store such information between calls. The main part of the state is token cache which is used for minimizing communication with the server as well as interaction with the user.

Which constructor should I use to create AuthentictionContext?

AuthenticationContext contructor has three parameters where only one of them (authority) is required:

  1. authority: is the STS that ADAL goes to for acquiring token. The address consists of an https url with a minimum of one segment in a path: e.g. https://login.microsoftonline.com/<tenant_name>/

If there is any extra path in the address, it will be ignored by ADAL.

  1. validateAuthority: a boolean flag which specifies whether to validate the authority before sending requests to it. The default value is true.

  2. tokenCache: an object to store access tokens and refresh tokens to save you from excessive trips to the authority in the future and also to minimize the need for user interaction (e.g. to enter credentials). If you do not pass this parameter, a default static token cache will be used.

Should I turn off authority validation by passing false to the constructor?

It depends on what type of authority you talk to. If it is ADFS, you have to pass false as ADFS does not currently support authority validation. If it is AAD, you still have the option to pass false, but it is recommended, especially if you get the address of the authority from a third party (e.g. via 401 challenge). This is to protect applications and users from being redirected to malicious endpoints to enter their credentials.

How to turn off token cache?

Pass null to the constructor, but this is not recommended. One of the main advantages of ADAL is to use refresh token to acquire new access token once it is expired. Turning off the cache, you will lose that feature which means excessive requests to the service and/or unnecessary user interaction.

What overload of AcquireToken should I call?

It depends on the type of client application you use and the scenario you need for token acquisition. This is your brief guidelines:

  1. ADAL supports two types of clients: public clients for native apps and confidential clients used mostly in web apps. If you have a client credential or certificate, your client is confidential and you can use any overload which has a parameter of type ClientCredential, ClientAssertion or ClientAssertionCertificate. Otherwise, you have a native client and can user any overload which does not need any of the above parameters.

  2. ADAL can acquire a token with either an user, an application, or both being the subject. If your scenario involves no user, you should call an overload of AcquireToken which does not have any mention of a user. For user flows or user plus application flows you can use the rest.

  3. For user only scenarios, ADAL can acquire token in interactive or non-interactive way. Interactive scenario involves a user entering his/her credential inside a browser control. Non-interactive scenario is used when the application already has user’s credential and can pass is using UserCredential class. This flow is however not recommended and should be only used in very limited cases with good reason not to use interactive flow instead.

  4. ADAL .NET also has overloads for advanced scenarios such as token acquisition for web apps by passing authorization code and also for on behalf of flow in which a user token is exchanged with a user plus app token.

Token Cache

Where is the token cache storage?

It depends on the platform. For desktop applications, the cache storage is in memory, but you can use the serialize method to store the content of the cache to any storage as a blob. You can then use the deserialize method to hydrate the cache from that blob. This is in fact a powerful tool for web applications with multiple users. A blob per user can be stored in a database.

On mobile platforms including Windows store and Windows phone and also Xamarin iOS and Android (ADAL v3), there is default persistent storage. However, you still have the option of using the serialize/deserialize methods. Also, there are three events which are invoked before and after cache access as well as before writing to the cache. You can use these events for advanced scenarios.

I do not get any token from the cache even though I think I have one there. What is the reason?

The arguments you pass to acquire token including the authority, resource, clientId and user’s unique Id or displayable Id make up the key for looking up the cache. If there is any mismatch (sometimes even in casing) may cause a cache miss. To make sure, you should enumerate the cache to find the problem.

Error Analysis

What are the common reasons for failure in using ADAL?

Problems in ADAL could have various reasons. These are the common culprits:

  1. Your machine has connection issues.

  2. Your applications/users are not properly configured on AAD or ADFS.

  3. You are using an incorrect API for your task (ADAL has several similar overloads for the method AcquireToken).

  4. There is a bug in ADAL! Yes, that is always possible. If you are certain that none of the items above are the reason for the failure, please report it to us and we will investigate and fix the bug if exists.

What tools can I use for diagnosing an issue in ADAL?

There are several diagnostics tools you can use:

  1. ADAL Samples: The first best tool is the set of samples published along with ADAL. Try to find the closest sample to your application and download and run it on your machine. If the sample works properly, you need to follow the same steps of the sample app in your application.

  2. ADAL diagnostic logs: You can turn on ADAL logs and then call the ADAL API. This will write some logs with information about the internal steps of ADAL. You may analyze the logs to find the issue. Also, in case you contact the ADAL team, you need to send the logs to help with the analysis. You can find the instruction on how to turn on ADAL logs here.

  3. Fiddler: is a powerful external tool for recording all the http communications ADAL makes with the server. Using fiddler is especially easy on Windows desktop machines. Fiddler trace is another useful document to share with the ADAL team in case we are involved in diagnosing your issue.

  4. ADAL Symbols and source files: ADAL is an open source project which makes it very convenient to debug. You can download the symbols file from the symbols server or even download the entire source code and reference it in your project instead of NuGet. More information about using ADAL source code can be found here.

What kind of errors are returned from ADAL as exception and what kind is reported to the user?

Most errors are returned from ADAL in forms of an exception; however, there are limited cases in which ADAL shows the error on the browser control. These cases happen mostly when the client cannot be validated or authority server cannot be reached.

Calling AcquireTokenSilent, I get an error with error code multiple_matching_tokens_detected. What is the problem?

You can find the conflict by enumerating the items in the cache (using context.TokenCache.ReadAll()). Then you can find which two items conflict. One common case is when you acquire token for two different users and then on the next call, pass no user.

Tokens in the cache are not returned when creating AuthenticationContext with common authority. What is the problem?

ADAL currently has a special behavior which may cause this observation. Common is not an actual tenant, but a placeholder for the tenant. When an AuthenticationContext is created using common authority (e.g. https://login.microsoftonline.com/common) on the first request to the authority, ADAL replaces common in the address with the actual tenant which is returned in response. Access token and refresh token are cached using the actual tenant in the key. Therefore, if you create a new context using common, the authority will not match the one in the cache. The solution is to store the authority from previous context (with the actual tenant) and initialize the new context using that.

Does ADAL have any kind of retry logic inside?

No. If an operations fails, ADAL reports an error via an exception. The exception includes an error code and also a status code in case the error is returned from the authority. In such cases, it is developer’s job to examine the status code (which mostly reflects the http status code of the response) in the exception and decides whether to retry or not. 502 is usually the status code that warrants a retry.

How should I report a problem to the ADAL team?

The first step is to explain the problem in details on StackOverflow website. Please use tag “adal”, so we can see your post. We try to engage with you and help you with the problem. We also recommend that you first browse the list of ADAL questions and answers on StackOverflow as it is possible that someone else has already faced the same problem and you may learn from the answers there.

If we decide that what you are observing is a bug in ADAL, we will ask you to open an issue on GitHub which is our open source repository. We will then triage the issues and fix them based on priorities in one of the upcoming servicing releases.

ADAL Release Model

How often does ADAL release a new version?

There is no pre-determined schedule. We try to publish servicing releases very regularly to fix bugs and unblock customers. Major releases usually take longer and we release several preview versions before general availability of a major version.

What is the compatibility model of ADAL versions?

The goal is to maintain backward compatibility within a major version. For that, we try to only fix bugs or add new features in servicing releases (which increase the minor version of ADAL). However, there is no compatibility guarantee between major versions. We may add or remove support for certain platforms or scenarios, therefore, you are recommended to fully understand the scope of the changes and fully test the new version of ADAL before switching to it in your production code.

ADAL for Windows Store

In ADAL for Windows store, how Windows Integrated Auth can be enabled?

User authentication in ADAL for Windows store is done via a Windows component called WebAuthentictionBroker. For that component to pass domain joined user’s kerbeos ticket to the ADFS server, multiple steps might be taken:

  1. App manifest capabilities “Enterprise Authentication” and “Shared User Certificates” should be enabled besides “Internet (Client)” which is needed for all user authentications in ADAL.

  2. Property UseCorporateNetwork in AuthenticationContext should be set to true.

  3. A special Uri needs to be registered as application’s redirectUri on Azure portal. That Uri can be retrieved via a call to method WebAuthenticationBroker.GetApplicationCallbackUri() within the same app.

  4. Null should be passed as redirectUri which makes ADAL use the same redirectUri as the one registered in step #3.

Why does ADAL for Windows store fails when in corporate network while it succeeds otherwise?

When in corporate network, requests to ADFS are automatically sent to the endpoint which expects Windows Intergrate Auth. However, if any of the conditions mentioned in the previous Q/A is not satisfied, ADAL fails to authentication the user.

TLS versions

If you require TLS 1.2, you might get errors when establishing the SSL connection. This is not due to ADAL.NET itself but tp the .Net Framework configuration: when you harden your environment, .NET by default tries an older version of the TLS but you can override it. This snippet is found in https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect-prerequisites#enable-tls-12-for-azure-ad-connect ; while the content says is for AAD Connect, this procedure is the same for all .NET clients

TSL version in desktop interactive login

On windows desktop, ADAL uses an embedded browser which is based on Internet Explorer (Web Browser control). The browser has its own TLS settings. Make sure TLS 1.2 is enabled.

image

Using ADAL with Kubernetes

  • Kubernetes expects an access token with the claim aud being spn:<webappguid> whereas AzureAD sends back a token with he claim aud being <webappguid>
  • to force AzureAD to send that form of audience in the token it's possible to use extra query parameters to set "api-version=1.0
  • Since extraQueryParameter does not exist in every overload of every flow, it's possible to set (even programmatically and locally using the Environment class in C#) the ExtraQueryParameter environment variable.
Clone this wiki locally