Proof-of-Possession (PoP) tokens - Microsoft Authentication Library for .NET (2024)

  • Article

Bearer tokens are the norm in modern identity flows; however they are vulnerable to being stolen from token caches.

Proof-of-Possession (PoP) tokens, as described by RFC 7800, mitigate this threat. PoP tokens are bound to the client machine, via a public/private PoP key. The PoP public key is injected into the token by the token issuer (Entra ID) and the clientalso signs the token using the private PoP key. A fully formed PoP token has two digital signatures - one from the token issuer and one from the client. The PoP protocol has two protections in place:

  • Protection against token cache compromise. MSAL will not store fully-formed PoP tokens in the cache. Instead, it will sign tokens only when the app requests them. An attacker who is able to compromise the token cache should not be able to digitally sign the incomplete tokens in there, as they do not have access to the PoP private key. The ability of an attacker to steal a private key can be mitigated by using hardware protected keys.
  • Protection against man-in-the-middle attacks. A server nonce is added to the protocol.

Warning

The strength of the PoP protocol depends in the strength of the PoP keys. Microsoft recommends using hardware keys via the Trusted Platform Module (TPM) where possible.

PoP Variants

There are several PoP protocols and variations. The Microsoft Entra ID infrastructure aims to supports two types:

  • PoP via Signed HTTP Request (SHR) . See PoP key distribution and SHR for the detailed specifications. This is fully supported by Entra ID and by the SDKs for public client scenarios, such as desktop and mobile applications.
  • PoP via mutual TLS (mTLS). See RFC 8705 for details. Investigated for confidential clients, i.e. web sites, web apis, server to server calls. No support exists currently.

mTLS is faster and has the advantage of including man-in-the-middle protections at the TLS layer; however, it can be difficult to establish mTLS tunnels between the client and the identity provider and between the client and the resource. PoP via Signed HTTP Request (SHR) does not rely on transport protocol changes; however the server nonce must be handled explicitly by the app developer.

Support for PoP SHR

Microsoft has enabled PoP via Signed HTTP Request (SHR) in some of its web APIs. Microsoft Graph supports PoP tokens. For example, if you make an unauthenticated request to https://graph.microsoft.com/v1.0/me/messages you will get a HTTP 401 response with two WWW-Authenticate headers, indicating bearer and PoP token support.

Proof-of-Possession (PoP) tokens - Microsoft Authentication Library for .NET (1)

Token validation

Microsoft does not currently offer a public SDK for PoP token validation.

Usage

Public client applications

PoP on public client flows can be achieved with the use of the Windows broker (WAM). Other MSAL libraries also support PoP through WAM.

The broker (via MSAL) will use the best available keys which exist on the machine, typically hardware keys (e.g., TPM). There is no option to bring your own key.

It is possible that a client does not support creating PoP tokens. This is caused by the fact that brokers (such as WAM or Company Portal) are not always present on the device or the SDK does not implement the protocol on a specific operating system. Currently, PoP tokens are available on Windows 10 and above, as well as Windows Server 2019 and above. Use IsProofOfPossessionSupportedByClient() to check if PoP is supported by the client.

Example

// Required for the use of the broker using Microsoft.Identity.Client.Broker; // The PoP token will be bound to this user / machine and to `GET https://www.contoso.com/tranfers` (the query parameters are not bound).// The nonce is a requirement in this case and needs to be acquired from the resource before using this API.// Server nonce is requiredstring nonce = "nonce";//HttpMethod is optionalHttpMethod method = HttpMethod.Get;//Request URIUri requestUri = new Uri("https://www.contoso.com/tranfers?user=me"); var pca = PublicClientApplicationBuilder.Create(CLIENT_ID) .WithBroker() //Enables the use of broker on public clients only .Build();//Interactive requestAuthenticationResult result = await pca .AcquireTokenInteractive(new[] { "scope" }) .WithProofOfPossession(nonce, method, requestUri) .ExecuteAsync() .ConfigureAwait(false);// The PoP token will be available in the AuthenticationResult.AccessToken returned form the acquire token call//To create the auth headervar authHeader = new AuthenticationHeaderValue(result.TokenType, result.AccessToken);//Silent requestvar accounts = await pca.GetAccountsAsync().ConfigureAwait(false);var result = await pca.AcquireTokenSilent(new[] { "scope" }, accounts.FirstOrDefault()) .WithProofOfPossession(nonce, method, requestUri) .ExecuteAsync() .ConfigureAwait(false);

Confidential client applications

Note

Proof-of-Possession via Signed HTTP Request is experimental for confidential clients and will likely be renamed or removed in a future version. Future APIs will rely on PoP via mTLS.

Example

// The PoP token will be bound to this user / machine and to `GET https://www.contoso.com/tranfers` (the query params are not bound).// Request URI is required in the PopAuthenticationConfiguration constructorPopAuthenticationConfiguration popConfig = new PopAuthenticationConfiguration(new Uri("https://www.contoso.com/tranfers?user=me"));//HttpMethod is optionalpopConfig.HttpMethod = HttpMethod.Get;// Server nonce is optionalpopConfig.Nonce = "nonce";//PopCryptoProvider is optional. Do not set to use MSAL's internal implementation.popConfig.PopCryptoProvider = new ECDCertificatePopCryptoProvider(); var cca = ConfidentialClientApplicationBuilder.Create(CLIENT_ID) .WithExperimentalFeatures() // Currently PoP for confidential client is an experimental feature .Build();result = await cca .AcquireTokenForClient (new[] { "scope"}) .WithProofOfPossession(popConfig) .ExecuteAsync() .ConfigureAwait(false);//The PoP token will be available on the AuthenticationResult.AccessToken returned form the acquire token call//To create the auth headervar authHeader = new AuthenticationHeaderValue(result.TokenType, result.AccessToken);

No hardware keys by default

MSAL.NET experimental API uses in-memory/software keys. An RSA key pair of length 2048 is generated by MSAL and stored in memory, cycled every eight hours. For details, see the implementation in PoPProviderFactory and InMemoryCryptoProvider.

Bring your own key

To use a better key, the API allows app developers to provide their own managed keys. The interface is an abstraction over the asymmetric key operations needed by PoP that encapsulates a pair of public and private keys and related crypto operations. All symmetric operations use SHA256.

Important

Two properties and the sign method on this interface will be called at different times but must return details of the same private/public key pair. Do not change to a different key pair through the process. It is best to make this class immutable. Ideally there should be a single public and private key pair associated with a machine. Implementers of this interface should consider exposing a singleton. See IPoPCryptoProvider, example RSA key implementation, and an example ECD key implementation for reference.

Adding more claims or creating the SHR request part of the PoP token

To create the SHR yourself, refer to the example implementation.

Proof-of-Possession (PoP) tokens - Microsoft Authentication Library for .NET (2024)
Top Articles
Moodle in English: Changing name and IP of moodle server | Moodle.org
Farmers Insurance - Page unavailable
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
Latest Posts
Article information

Author: Gregorio Kreiger

Last Updated:

Views: 6713

Rating: 4.7 / 5 (57 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Gregorio Kreiger

Birthday: 1994-12-18

Address: 89212 Tracey Ramp, Sunside, MT 08453-0951

Phone: +9014805370218

Job: Customer Designer

Hobby: Mountain biking, Orienteering, Hiking, Sewing, Backpacking, Mushroom hunting, Backpacking

Introduction: My name is Gregorio Kreiger, I am a tender, brainy, enthusiastic, combative, agreeable, gentle, gentle person who loves writing and wants to share my knowledge and understanding with you.