Giter Site home page Giter Site logo

microsoft-authentication-extensions-for-dotnet's Introduction

Note This package continues to be maintained alongside Microsoft.Identity.Client repository. Microsoft.Identity.Client.Extensions.Msal will be versioned in sync with Microsoft.Identity.Client. No breaking changes exist between version 2.x and version 4.x.

MSAL token cache extension for public client applications

A cross-platform token cache serialization mechanism - see details on the Wiki.

NuGet

Build Status

We have renamed the default branch to main. To rename your local repo follow the directions here.

Samples

We aim to have all MSAL public client samples use the extensions.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

microsoft-authentication-extensions-for-dotnet's People

Contributors

bgavrilms avatar crmann1 avatar devigned avatar erich-wang avatar gaspardpetit avatar jmprieur avatar jpwilli avatar keegan-caruso avatar markzuber avatar microsoftopensource avatar mrward avatar msftgits avatar neha-bhargava avatar pmaytak avatar sameerk-msft avatar trwalke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

microsoft-authentication-extensions-for-dotnet's Issues

Null Ref exception when reading data from an unavailable source

  1. Install LibSecret but no wallet
  2. Reading from LibSecret will return null instead of a 0 byte array. This causes the exception below:

Microsoft.Identity.Client.Extensions.TraceSource Error: 0 : An exception was encountered while reading data from the MsalCacheStorage : System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.Identity.Client.Extensions.Msal.MsalCacheStorage.ReadData() in /home/bogdan/microsoft-authentication-extensions-for-dotnet/src/Microsoft.Identity.Client.Extensions.Msal/MsalCacheStorage.cs:line 135

Share macOS Keychain items without prompts/create ACLs

By default when an application creates a macOS Keychain item the access control list contains the calling application's identity. This prevents those allow/deny/always allow security prompts when the same application accesses the item.

If an application that is not present in the ACL attempts to read/write the entry the security prompt is shown. Clicking "Deny" obviously declines the access request, and clicking "Allow" permits the operation just-this-time. Clicking "Always Allow" adds a new ACL for the calling application to the item, preventing future prompts.

Given one of the reasons to use this library is to facilitate sharing of a token cache between applications, it would be nice if there was a utility method on the MsalCacheHelper to forcibly add/ensure the calling application is present on the item's ACL.

The benefit here would be that users are only prompted once and that the option to just "Allow [once]" is not presented.

If there are other ways to avoid this prompt, such as Keychain groups/sharing based on the codesigning team identifier, then that would be even better, but there should be documentation about how to correctly use the library and set up such sharing.

Note that I'm not sure that Keychain groups/sharing is supported on non-iOS/iCloud keychains? There isn't a great deal of documentation from Apple here.

MsalCacheHelper.Clear() method - change behavior instead of deprecation

Following offline talk with Bogdan, we agreed that it is better instead of deprecating the MsalCacheHelper.Clear() method, to change its behavior that it will only clear the cache entries relevant to the specific public client application id that the MsalCacheHelper object was created with, and not whole entries in the cache file itself.

On Linux, accessing the KeyRing via SSH while also having a desktop session open causes the process to hang

Encountered by @erich-wang while testing. No known user impact.

Repro steps

  1. Start a user session on Ubuntu
  2. Also connect to Ubuntu via SSH
  3. On the SSH connection, login using PowerShell

Actual: PowerShell hangs. On the desktop session KeyRing displays a window asking the user to unlock the session.
Expected: PowerShell should not hang

Potential fix: detect if the current session is interactive or not (simple to do). If it is not interactive, do not try KeyRing, immediately use the fallback.

KeyRing and KeyChain should touch the file cache, not overwrite it

  1. Setup persistence on Linux with fallback
  2. Connect via SSH and login - file cache fallback is used
  3. Connect again via Gnome UI. Login - KeyRing is used
  4. Connect again via SSH

Actual: SSO is lost, user needs to re-login
Expected: SSO should not be lost

Solution: instead of overwriting token cache file, just touch it.

[Bug] token cache file not getting created when referencing DLLs instead of nupkg

            app = PublicClientApplicationBuilder.Create(clientId).WithTenantId(tenant).WithAuthority(authority).Build();
            StorageCreationPropertiesBuilder storageCreationPropertiesBuilder = new StorageCreationPropertiesBuilder("tokenCache.dat", "tokencache", clientId).
                WithLinuxKeyring("test", "default", "Get Access Token",
                new System.Collections.Generic.KeyValuePair<string, string>("Version", "1"),
                new System.Collections.Generic.KeyValuePair<string, string>("ProductGroup", "Test")).WithMacKeyChain("Test", "default");
            var task = Task.Run(async () => await MsalCacheHelper.CreateAsync(storageCreationPropertiesBuilder.Build()));
            MsalCacheHelper msalCacheHelper = task.Result;
            try
            {
                msalCacheHelper.RegisterCache(app.UserTokenCache);
                Task<AuthenticationResult> result = app.AcquireTokenByIntegratedWindowsAuth(scopes).WithUsername(username).ExecuteAsync();
                Console.Write(result.Result.AccessToken);
            }

I am using Microsoft.Identity.Client -> 4.15.0 and Microsoft.Identity.Client.Extensions -> 2.12.0. The issue is that tokencache folder gets created but tokenCache.dat doesnt get created. I am having the DLLs downloaded from the respective Nuget packages and adding them as a Reference in the .NET core console project.

This works absolutelyt fine and cache file gets created If I directly link the package from Nuget package manager. I am not really sure what is happening here. It might not be a bug, but want to see if anyone can help here?

"SecKeychainFindGenericPassword failed with error code -25293" when calling RegisterCache()

We're trying to enable user token caching in our desktop application in OS X. We modeled the caching after the manual test app https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/d32a5a6eb699cc652ca08c477140af1a0a0dbd42/tests/ManualTestApp/Program.cs. However, when running on mac, once we sign in the first time, get a Keychain Access entry and then try to sign in again, we get the error "SecKeychainFindGenericPassword failed with error code -25293" with the following stack trace:
at Microsoft.Identity.Client.Extensions.Msal.MacKeyChain.DeleteKey(String serviceName, String accountName) at Microsoft.Identity.Client.Extensions.Msal.MsalCacheStorage.ClearCore() at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.RegisterCache(ITokenCache tokenCache).

The problem goes away after we manually go into Keychain Access, click on the keychain entry corresponding to our token, and change the Access Control setting to "Allow all applications to access this item". I noticed the wiki mentions this:

Mac offers a more restricted scope, ensuring that only the application that created the cache can access it, and prompting the user if others apps want access.

Does this mean this is the intended behavior? Is there anyway to circumvent this issue that doesn't require users to manually change the Keychain Access Control settings for their entry?

MacKeyChain uses "Legacy" APIs

The APIs that are being used on MacOS are not deprecated, but are marked as "Legacy" and their use is discouraged.

https://developer.apple.com/documentation/security/keychain_services/keychain_items?language=objc#1659107

This may not be an immediate issue, but Apple may deprecate and then remove them in the future, and they don't support more advanced scenarios such as Sharing Access to Keychain Items Among a Collection of Apps.

The P/Invoke also doesn't use utf-8 encoded strings, so may cause issues with non-ascii characters in the service or account names.

RefreshTokens with CA claims can be overriden by the current cache implementation

Not all Refresh Tokens (RT) are the same. RTs are different after Conditional Access mechanism have been satisfied.

Current locking strategy around AcquireTokenSilent is:

  1. Acquire a lock. Read the cache in memory. Release the lock
  2. Business logic (e.g. go to evo to get new tokens)
  3. Acquire a lock. Read the cache in memory. Merge new tokens. Write cache from memory. Release lock.

Bug repro

app A begins an AcquireTokenSilent and releases the lock after step 1
app B begins an AcquireTokenInteractive and user resolves CA. An RT with CA claims is saved to the cache.
app A receives new tokens and merges them into the token cache (step 3). This overrides the RT with CA claims.

Actual: RT with CA state should be in the cache
Expected: RT with CA state is deleted

Note: because AcquireTokenInteractive takes much longer than AcquireTokenSilent, it is unlikely that this bug will occur

After the user logs out, they can find themselves still logged in

Current locking strategy around AcquireTokenSilent is:

  1. Acquire a lock. Read the cache in memory. Release the lock
  2. Business logic (e.g. go to evo to get new tokens)
  3. Acquire a lock. Read the cache in memory. Merge new tokens. Write cache from memory. Release lock.

This exposes the possibility of:

  • app A begins an AcquireTokenSilent and releases the lock after step 1
  • during step 2, app B logs out the user (removes account and associated tokens)
  • app A receives new tokens and merges them into the token cache (step 3). This adds back the user to the cache.

Actual: the current user is still logged in
Expected: the current user should be logged out

Cache helper in a .NET (Framework) service

I want to use the cache helper to share the cache between my system tray UI app (.NET Framework Desktop app) and my background service (.NET Framework service)

My UI app can read and write my cache file but my system is not able to access it.

Any Hints ?

MsalCacheHelper.GetAccountIdentifiersAsync needs CrossPlatLock

When reacting to a cachefile changed event, we create a new PCA and read the cache, looking for added/removed accounts. This isn't behind a CrossPlatLock though, so it can and will try to access the actual cache when it's not available. The fix is to add a CrossPlatLock in the temporary PCA created in that method.

Missing documentation

I don't see any documentation, or links to documentation on MSDN, to outline what this library does or what use cases it is intended to help.

Increase concurrency level to 40+ threads

When multiple threads / two processes use the MsalCacheHelper, it throws the following exception:
System.InvalidOperationException: Could not get access to the shared lock file. ---> System.IO.IOException: The process cannot access the file 'C:\Users\yosefd\AppData\Roaming\Kusto\userTokenCache.data.lockfile' because it is being used by another process.

We experienced this via a command line tool we have. When it runs for enough time, sporadically, authentication pop-ups appear and if not confirmed, the connection fails on timeout. Each time there is a pop-up, we see that exception.

More background about how weโ€™re reproducing the error:
This happened on Windows 10, both when Kusto Explorer (another tool of ours that uses the MsalCacheHeper) was running and also when it was not running. The exception happens in the context of that command-line tool, and not Kusto Explorer. The tool that hits these exceptions was running alone (one process). It had many concurrent threads, about 150, and all were performing remote calls.

NullRef on Xamarin.Mac when TraceSource is set to null

var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

Produces a null ref on Xamarin.Mac only.

Workaround - use a TraceSource for logging:

var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties, new TraceSource("my_app_token_cache")).ConfigureAwait(false);

[FEATURE ASK] Provide general encryption and decryption method

MSAL extension should provide encrption/decryption methods for general purpose, it may look like:

	byte[] Encrypt(SecureString ); //or return as base64 string?
	SecureString Decrypt(byte[] );

Besides token info, we want to protect client secret of service principal as well, currently in Azure PowerShell client secret of service principal is saved as plain text which doesnโ€™t meet secret review. MSAL extension for Python has provided similar functionality, you may find the sample code here

[Bug] Null Reference Exception Thrown in RegisterCache on Mac

image
When RegisterCache is run on mac a null reference is thrown in Msal.MacKeyChain.DeleteKey(String serviceName, String accountName). This issue does not appear on linux or windows at the moment.

Issue appears on Mac OS 11.4 (20F71)
Msal version 2.18.7

PlatformNotSupportedException on MacOS via Xamarin / Make CacheChanged event configurable

I tried to implement token serialization as described here for my Xamarin.MacOS app. However, I am hitting this exception:

System.PlatformNotSupportedException: Operation is not supported on this platform.
  at System.IO.FileSystemWatcher.StartRaisingEvents () [0x00000] in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.UnknownUnix.cs:23 
  at System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed () [0x00019] in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs:664 
  at System.IO.FileSystemWatcher.set_EnableRaisingEvents (System.Boolean value) [0x0001d] in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs:163 
  at (wrapper remoting-invoke-with-check) System.IO.FileSystemWatcher.set_EnableRaisingEvents(bool)
  at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.CreateAsync (Microsoft.Identity.Client.Extensions.Msal.StorageCreationProperties storageCreationProperties, System.Diagnostics.TraceSource logger) [0x000bc] in <e1855c7c1c93442fa2635ff71c06cc54>:0 

My code:

var storageProperties = new StorageCreationPropertiesBuilder("msal_cache.dat", Environment.GetFolderPath(Environment.SpecialFolder.Personal), ClientId)
    .WithMacKeyChain("msal_service", "msal_account")
    .Build();
var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties);

Memory leak of ITokenCache objects

  1. Create singleton MsalCacheHelper
  2. Create a bunch of PublicClientApplication objects (common scenario - one per authority, one per client id, etc.)
  3. For each PublicClientApplication call helper.RegisterCache(pca.UserTokenCache)
  4. Let PublicClientApplication be garbage collected

Actual: the UserTokenCache objects do not get cleanded up leading to a small memory leak.

Note: this is a customer reported problem

link to linux fallback configuration example does not work

I'm trying to test whether token caching works for our desktop app on linux, but I can't do it over ssh. I noticed the wiki states

KeyRings does not work in headless mode (e.g. when connected over SSH or when running Linux in a container) due to a dependency on X11. To overcome this, a fallback to a plaintext file can be configured. See this example for how to configure it.

But when I click the link to the example, I get a github 404 error. Can the wiki please be updated?

[Feature Request] Cache Helper object should not need client ID

Currently, the top level object requires to be created by passing in a client ID. Internally this is only used to produce the CacheChanged event, which many consumers do not care about.

We should allow creation of this top level object without a client ID.

Prevent PlatformNotSupportedException to be thrown

In order to have my macOS app to break at the location where an exception is thrown, I enabled a global Exception catchpoint:
Screenshot 2020-11-25 at 18 05 14

Now this causes my app to break every time I call MsalCacheHelper.CreateAsyncbecause a PlatformNotSupportedException is being thrown internally (see #61).

Is there perhaps a way to prevent the exception to be thrown so my app is not switching into debugging mode?

Add better exception message for when accessing the keychain fails on SSH

The login Keychain is not unlocked when connecting via an SSH session. You can manually do this by running:

security unlock-keychain -p $PASSWORD $KEYCHAIN

..where PASSWORD is the userโ€™s password, and KEYCHAIN is the path to the userโ€™s login Keychain (i.e, /Users//Library/Keychains/login.keychain-db).

Itโ€™s not very elegant but does seem to work in my limited testing.
Probably something you could detect (a locked keychain from a remote session), catch the error, and tell the user to manually unlock the login Keychain with that command?

Upgraded to latest pkg broken saving cache

We were on .NETCore 3.0 and these versions:
PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="2.15.0"
PackageReference Include="Microsoft.Identity.Client" Version="4.25.0"

Now upgraded to .NETCore 3.1 with the latest:
PackageReference Include="Microsoft.Identity.Client" Version="4.25.0"
PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="2.16.8"

I was not able to see precisely which version broke things because of NuGet pkg downgrade dependency hell.

Msal continues to work prompting for authentication via the browser (and succeeds) but saving to the cache no longer works. A new cache file is created but upon subsequent relaunch of the app the cache no longer succeeds and the user is prompted again.

var user = "unknown"; string domainaccount = WindowsIdentity.GetCurrent().Name; if (!String.IsNullOrWhiteSpace(domainaccount)) { var domainaccountSplit = domainaccount.Split('\\'); if (domainaccountSplit.Length >= 2) { user = domainaccountSplit[1]; } }
		var myApp_AppData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft\\MyApp");
        var storageCreationPropertiesBuilder = new StorageCreationPropertiesBuilder(
            $"MyApp.{user}.msalcache.bin3",
            myApp_AppData,
            MyAppClientAppGuid.ToString()
            );
        var storageCreationProperties = storageCreationPropertiesBuilder.Build();
        var msalCacheHelper = MsalCacheHelper.CreateAsync(storageCreationProperties).GetAwaiter().GetResult();
        msalCacheHelper.RegisterCache(app.UserTokenCache);


        AuthenticationResult result;
        var account = app.GetAccountsAsync().GetAwaiter().GetResult().FirstOrDefault();

        try
        {
            result = app
                .AcquireTokenSilent(scopes, account)
                .ExecuteAsync()
                .GetAwaiter()
                .GetResult();


        }
        catch (MsalUiRequiredException)
        {
            result = app
                .AcquireTokenInteractive(scopes)
                .ExecuteAsync()
                .GetAwaiter()
                .GetResult();
        }

        return result;

</Code Snippet>

When installing the NuGet package, a link to the license file is added to the .csproj

For some reason, when installing the NuGet package in a .NET Core console app, a link to the package's License file appears under the .csproj.
image

When trying to remove this link, I get the following message:
image

Examining this file reveals the following section which adds the link to the License file:

  <ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
    <None Include="$(NuGetPackageRoot)microsoft.identity.client.extensions.msal\2.1.0-preview\contentFiles\any\netcoreapp2.1\LICENSE" Condition="Exists('$(NuGetPackageRoot)microsoft.identity.client.extensions.msal\2.1.0-preview\contentFiles\any\netcoreapp2.1\LICENSE')">
      <NuGetPackageId>Microsoft.Identity.Client.Extensions.Msal</NuGetPackageId>
      <NuGetPackageVersion>2.1.0-preview</NuGetPackageVersion>
      <NuGetItemType>None</NuGetItemType>
      <Private>False</Private>
      <Link>LICENSE</Link>
    </None>
  </ItemGroup>

Is this intentional? I believe it is a bug and not a feature.
I tried on both VS2017 and VS2019 Preview.

[Bug] Azure.Identity.AuthenticationFailedException from Windows

The issue comes from Azure/azure-powershell#14861. Please let us know what needs user's further check? and Is there any workaround.

A similar issue is Azure/azure-powershell#13691. but stack trace is a little different.

Which Version of MSAL are you using ?

Microsoft.Identity.Client.Extensions.Msal 2.16.6.0

Platform

What authentication flow has the issue?

  • Desktop / Mobile
    • Interactive
    • Integrated Windows Auth
    • Username Password
    • Device code flow (browserless)
  • Web App
    • Authorization code
    • OBO
  • Daemon App
    • Service to Service calls

Other? - please describe;

Is this a new or existing app?

Repro

var your = (code) => here;

Expected behavior
A clear and concise description of what you expected to happen (or code).

Actual behavior
A clear and concise description of what happens, e.g. exception is thrown, UI freezes

Possible Solution

Additional context/ Logs / Screenshots
Add any other context about the problem here, such as logs and screebshots.

DEBUG: InteractiveBrowserCredential.Authenticate was unable to retrieve an access token. Scopes: [
https://management.core.windows.net//.default ] ParentRequestId:  Exception:
Azure.Identity.AuthenticationFailedException (0x80131500): InteractiveBrowserCredential authentication failed:
Persistence check failed. Inspect inner exception for details
 ---> Microsoft.Identity.Client.Extensions.Msal.MsalCachePersistenceException (0x80131500): Persistence check failed.
Inspect inner exception for details
 ---> System.Security.Cryptography.CryptographicException (0x80070000): The operation completed successfully.

WARNING: Unable to acquire token for tenant 'organizations'

WARNING: Please run 'Connect-AzAccount -DeviceCode' if browser is not supported in this session.

DEBUG: Azure.Identity.AuthenticationFailedException: InteractiveBrowserCredential authentication failed: Persistence
check failed. Inspect inner exception for details --->
Microsoft.Identity.Client.Extensions.Msal.MsalCachePersistenceException: Persistence check failed. Inspect inner
exception for details ---> System.Security.Cryptography.CryptographicException: The operation completed successfully.

   at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy,
DataProtectionScope scope)
   at Microsoft.Identity.Client.Extensions.Msal.DpApiEncryptedFileAccessor.Read()
   at Microsoft.Identity.Client.Extensions.Msal.MsalCacheStorage.VerifyPersistence()
   --- End of inner exception stack trace ---
   at Microsoft.Identity.Client.Extensions.Msal.MsalCacheStorage.VerifyPersistence()
   at Azure.Identity.PersistentTokenCache.<GetCacheHelperAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.PersistentTokenCache.<RegisterCache>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.MsalClientBase`1.<GetClientAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.MsalPublicClient.<AcquireTokenInteractiveAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.InteractiveBrowserCredential.<GetTokenViaBrowserLoginAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.InteractiveBrowserCredential.<AuthenticateImplAsync>d__30.MoveNext()
   --- End of inner exception stack trace ---
   at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex)
   at Azure.Identity.InteractiveBrowserCredential.<AuthenticateImplAsync>d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Azure.Identity.InteractiveBrowserCredential.<AuthenticateAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.PowerShell.Authenticators.MsalAccessToken.<GetAccessTokenAsync>d__34.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Azure.Commands.Common.Authentication.Factories.AuthenticationFactory.Authenticate(IAzureAccount
account, IAzureEnvironment environment, String tenant, SecureString password, String promptBehavior, Action`1
promptAction, IAzureTokenCache tokenCache, String resourceId)
   at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.AcquireAccessToken(IAzureAccount account,
IAzureEnvironment environment, String tenantId, SecureString password, String promptBehavior, Action`1 promptAction)
   at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.ListAccountTenants(IAzureAccount account,
IAzureEnvironment environment, SecureString password, String promptBehavior, Action`1 promptAction)
   at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.Login(IAzureAccount account, IAzureEnvironment
environment, String tenantId, String subscriptionId, String subscriptionName, SecureString password, Boolean
skipValidation, Action`1 promptAction, String name, Boolean shouldPopulateContextList, Int32 maxContextPopulation)
   at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass111_2.<ExecuteCmdlet>b__4()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at
Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass111_0.<ExecuteCmdlet>b__1(AzureRmProfile
 localProfile, RMProfileClient profileClient, String name)

Archive this repo

@henrik-me @jmprieur -
Can we archive this repo now that the extensions are in the same repo as MSAL ? There is one outstanding PR from Mark and 1-2 issues that we'd need to move.

WCF Azure App service

Hello, I have a WinForms (legacy) client application that consumes WCF services and uses its own authentication model... (on-premises)

However, the company wants to migrate to Azure and use an app service to host the wcf and authenticate it with Azure AD (JWT).

Do you have any example with this scenario?

winforms + (app service + wcf + azure AD (JWT))

Thank you

Users of the extension should not be able to call low-level MsalCacheStorage APIs

Context
Msal Extension has two ways of achieving the same thing, i.e. providing a token cache:

  • MsalCacheStorage, a low level access to the persistence level, that is not protected with locks. Developers need to write their own token cache delegates, which they often get wrong.

  • MsalCacheHelper, a higher level abstraction, which provides token cache delegates that are consistent cross-process.

Problem
Developers tend to choose the lower-level API MsalCacheStorage. This breaks other libraries or results in high contention, because there are strict rules about file locking, file writing etc. which are not followed.

Proposed Solution
Make MsalCacheStorage internal. Developers must use MsalCacheHelper only (example usage here)

There may some functionality that people rely on for MsalCacheStorage, which we need to capture:

  1. Powershell needs to import and export the cache data and they do it using MsalCacheStorage. This can be fixed by adding Import / Export methods in MsalCacheHelper

[Feature Request] Use credential manager instead of local file store for token caching on Windows platforms

Is your feature request related to a problem? Please describe.
I'm used to most other credential manager type functions to use Credential Manager in windows (e.g. git and nuget credential managers both do this on windows IIRC). It seems inherently more secure -- I'm assuming cred manager access is audited, and that permissions are more tightly controlled than they might be in a file system. This feature request might just as well be the question: Why is MSAL using local file storage instead of the credential manager store?

Describe the solution you'd like
Having windows execution use Credential Manager to store tokens.

Describe alternatives you've considered
I think the existing implementation is an alternative, but it seems less secure than using credential manager.

Cache helper does not work UWP apps

I was super excited to try this out instead of doing my own serialization for my UWP app.

But it doesn't work due to code here:
https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/c23dd2c211f88143b583a3dd69e50cc55b8c7e43/src/Shared/SharedUtilities.cs

As it is trying to retrieve information about the OS en

Exception thrown: 'System.PlatformNotSupportedException' in System.Diagnostics.Process.dll
Retrieving information about local processes is not supported on this platform.

The documentation here:
https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization

Isn't very clear about serialization for UWP apps.

It mentions "in-memory" followed "serialization by default". Does that mean that I don't need to serialize to disk for UWP apps (mine is running on a non-mobile platform).

That documentation also states that custom serialization isn't available for UWP, which is odd, because that's precisely what I'm currently doing :)

AcquireTokenForClient Stuck when application hosted in IIS

Hi,

I am trying to acquire Token using certificate to connect Graph API. Its works in console application and local IIS express.

However, when hosted same in IIS it get stuck and timed out.

Code Snippet:

           var msalClient = ConfidentialClientApplicationBuilder
            .Create(config.ClientID)
            .WithCertificate(GetCertificateByThumbprint(config.ApplicationThumbprint))
            .WithAuthority(AadAuthorityAudience.AzureAdMyOrg, true)
            .WithTenantId(config.TenantID)
            .Build();

         result = await msalClient.AcquireTokenForClient(scopes).ExecuteAsync(); // **Gets Stuck** - IT DOES EVEN GO TO NEXT STEP

        requestMessage.Headers.Authorization =
            new AuthenticationHeaderValue("bearer", await GetAccessTokenAsync());

        var users = await graphClient.Users.Request().Filter($"mail eq '{emailAddress}'").GetAsync();

I have createD ASP.NET MVC for poc and will convert into Web API.

I do not want to use user login token or such... There is no login page and we want to interact MS Graph API using application specific Client ID.

Please some one help on this.

thank you!

CrossPlatLock does not work on UWP

the following line in CrossPlatLock.cs does not work on UWP and results in a SystemException: Retrieving information about local processes is not supported on this platform.

writer.WriteLine($"{Process.GetCurrentProcess().Id} {Process.GetCurrentProcess().ProcessName}");

Unresolved P/Invoke method build warning for UWP using msal

We've received the following build warning for our UWP app which uses Microsoft.Identity.Client 4.22.0 and Microsoft.Identity.Client.Extensions.Msal 2.16.5.

The app and authentication appears to be working ok, but I wondered if this is a problem, or there is something we need to do to fix the warning?

##[warning]C:\Users\VssAdministrator\.nuget\packages\microsoft.net.native.compiler\2.2.9-rel-29512-01\tools\Microsoft.NetNative.targets(805,5): Warning : MCG : warning MCG0007: Unresolved P/Invoke method 'libsecret-1.so.0!secret_schema_new' for method 'System.IntPtr Microsoft.Identity.Client.Extensions.Msal.Libsecret.secret_schema_new(System.String, System.Int32, System.String, System.Int32, System.String, System.Int32, System.IntPtr)'. Calling this method would throw exception at runtime. Please make sure the P/Invoke either points to a Windows API allowed in UWP applications, or a native DLL that is part of the package. If for some reason your P/Invoke does not satisfy those requirements, please use [DllImport(ExactSpelling=true) to indicate that you understand the implications of using non-UWP APIs.

We receive about 10 similar warnings for different P/Invoke methods related to the package - is the possible runtime exception something we can fix?

Corrupt cache should be deleted

Currently if decryption of the cache fails we delete the cache. The same should be true if the cache cannot be deserialized.

If the cache is not deleted then using the cache will cause the public client application to not function since it can never load it off disk and just throws an exception .

For example take a cache, and corrupt it, or just put a space in the file. You should see this exception. You will continue to get this exception until the cache is manually deleted.

'Microsoft.Identity.Client.MsalClientException: MSAL V3 Deserialization failed to parse the cache contents. Is this possibly an earlier format needed for DeserializeMsalV2? (See https://aka.ms/msal-net-3x-cache-breaking-change)
at IDictionary<string, JToken> Microsoft.Identity.Client.Cache.TokenCacheJsonSerializer.Deserialize(byte[] bytes, bool clearExistingCacheData)
at void Microsoft.Identity.Client.TokenCache.Microsoft.Identity.Client.ITokenCacheSerializer.DeserializeMsalV3(byte[] msalV3State, bool shouldClearExistingCache)
at Task<HashSet> Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.GetAccountIdentifiersAsync(StorageCreationProperties storageCreationProperties)+(TokenCacheNotificationArgs args) => { }
at async Task Microsoft.Identity.Client.TokenCache.Microsoft.Identity.Client.ITokenCacheInternal.OnBeforeAccessAsync(TokenCacheNotificationArgs args)
at async Task Microsoft.Identity.Client.Cache.CacheSessionManager.RefreshCacheForReadOperationsAsync(TokenTypes cacheEventType)
at async Task<IEnumerable> Microsoft.Identity.Client.Cache.CacheSessionManager.GetAccountsAsync(string authority)
at async Task<IEnumerable> Microsoft.Identity.Client.ClientApplicationBase.GetAccountsAsync()
at async Task<HashSet> Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.GetAccountIdentifiersAsync(StorageCreationProperties storageCreationProperties)
at async Task Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.CreateAsync(StorageCreationProperties storageCreationProperties, TraceSource logger)

MsalCacheHelper.CreateAsync throws HttpRequestException when offline

Desired behavior
I would like to be able to read the accounts from the cache, even when the user does not have an internet connection. It is my understanding that this functionality works when using MSAL with token caches on other platforms. Is there any reason offline functionality should not be possible with the token cache provided in this repo?

Actual behavior
When I call MsalCacheHelper.CreateAsync, it throws a HttpRequestException with the message No such host is known.

Miscellaneous

  • The app I am using is a .NET 5.0 WPF app.
  • I am using version 2.16.7 of Microsoft.Identity.Client.Extensions.Msal

persistent cache resiliency

Taking to account that file locks are not completely reliable on non Win platforms, It would be nice to implement following features to be race conditions resilient:

  • Switch file cache accessor from non-atomic file writes to atomic file renaming (in order to prevent dirty reads + dirty writes - cache corruption)
  • Retry logic on KeyChainAccessor to deal with race conditions

details can be found here -> https://github.com/AzureAD/microsoft-authentication-extensions-for-java/wiki/Race-conditions

Extension should not crash on Linux if LibSecret 1.so.0 is not present

  1. Use a machine where LibSecret is not present, e.g. Ubuntu 16.04 Azure version
  2. Bind the cache, for example run the ManualTestApp

Actual:

An exception of type 'System.DllNotFoundException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Unable to load shared library 'libsecret-1.so.0' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibsecret-1.so.0: cannot open shared object file: No such file or directory'
at Microsoft.Identity.Client.Extensions.Msal.Libsecret.secret_schema_new(String name, Int32 flags, String attribute1, Int32 attribute1Type, String attribute2, Int32 attribute2Type, IntPtr end)
at Microsoft.Identity.Client.Extensions.Msal.CacheAccessorLinux.GetLibsecretSchema() in /home/bogdan/microsoft-authentication-extensions-for-dotnet/src/Microsoft.Identity.Client.Extensions.Msal/Os/Linux/CacheAccessorLinux.cs:line 148
at Microsoft.Identity.Client.Extensions.Msal.CacheAccessorLinux.Clear() in /home/bogdan/microsoft-authentication-extensions-for-dotnet/src/Microsoft.Identity.Client.Extensions.Msal/Os/Linux/CacheAccessorLinux.cs:line 31
at Microsoft.Identity.Client.Extensions.Msal.MsalCacheStorage.ReadData() in /home/bogdan/microsoft-authentication-extensions-for-dotnet/src/Microsoft.Identity.Client.Extensions.Msal/MsalCacheStorage.cs:line 140
at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.RegisterCache(ITokenCache tokenCache) in /home/bogdan/microsoft-authentication-extensions-for-dotnet/src/Microsoft.Identity.Client.Extensions.Msal/MsalCacheHelper.cs:line 242
at ManualTestApp.Program.d__4.MoveNext() in /home/bogdan/microsoft-authentication-extensions-for-dotnet/tests/ManualTestApp/Program.cs:line 223

MsalCacheHelper.CreateAsync throws MsalClientException when using an ADFS ClientId

When trying to use MsalCacheHelper with a ClientId for ADFS which is not a GUID the followoing exception is thrown.

MSAL.NetCore.4.16.1.0.MsalClientException:
ErrorCode: client_id_must_be_guid
Microsoft.Identity.Client.MsalClientException: Error: ClientId is not a Guid.
  at Microsoft.Identity.Client.AbstractApplicationBuilder1.Validate() 
  at Microsoft.Identity.Client.PublicClientApplicationBuilder.Validate() 
  at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.GetAccountIdentifiersAsync(StorageCreationProperties storageCreationProperties, TraceSourceLogger logger) 
  at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.CreateAsync(StorageCreationProperties storageCreationProperties, TraceSource logger)

To reproduce this you can run the following.

StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder("msal.cache", ".", "AdfsNonGuidClientId").Build();

await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

To work around this issue I'm updating the code to supply a random guid rather than a specific client id. The client id doesn't seem to be necessary as the MsalCacheHelper only uses it to create a PublicClientApplication to iterate through the accounts in a serialized cache, in the method GetAccountIdentifiersAsync

private static async Task<HashSet<string>> GetAccountIdentifiersAsync(
StorageCreationProperties storageCreationProperties,
TraceSourceLogger logger)
{
var accountIdentifiers = new HashSet<string>();
if (File.Exists(storageCreationProperties.CacheFilePath))
{
var pca = PublicClientApplicationBuilder.Create(storageCreationProperties.ClientId).Build();
pca.UserTokenCache.SetBeforeAccess((args) =>
{
MsalCacheStorage tempCache = null;
try
{
tempCache = MsalCacheStorage.Create(storageCreationProperties, s_staticLogger.Value.Source);
// We're using ReadData here so that decryption is handled within the store.
var data = tempCache.ReadData();
args.TokenCache.DeserializeMsalV3(data);
}
catch (Exception e)
{
logger.LogError("An error occured while reading the token cache: " + e);
logger.LogError("Deleting the token cache as it might be corrupt.");
tempCache.Clear();
}
});
var accounts = await pca.GetAccountsAsync().ConfigureAwait(false);
foreach (var account in accounts)
{
accountIdentifiers.Add(account.HomeAccountId.Identifier);
}
}
return accountIdentifiers;
}

AadIssuerValidator usage

The code in this file: https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/master/src/Microsoft.Identity.Client.Extensions.Web/Resource/AadIssuerValidator.cs

is replicated in many MSFT samples using AADv2, aka https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/master/Microsoft.Identity.Web/Resource/AadIssuerValidator.cs

Also, this code is not part of a nuget package, even a preview, at this time.

should one just copy this code into their own project if they want to use the AadIssuerValidator?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.