Answer the claims challenge on activation - #8
Merged
Merged
Conversation
A role can sit behind a Conditional Access authentication context, which PIM enforces at the moment of activation rather than at sign-in. The refusal carries a claims challenge, and it was being discarded, so such a role could not be activated at all however many times you signed in again. The challenge is now dug out of the message it is buried in, answered with a sign-in carrying those claims, and the request that was refused is sent once more, unchanged. A second refusal is reported as it came back, so a context this tool cannot satisfy is not disguised as the original failure. The claims are never sent unprompted. Which authentication contexts exist and which roles require them is a per-tenant setting, so asking for one would fail in a tenant that has not defined it and prompt for nothing in one that has. A token issued for a challenge is cached apart from the ordinary one, since neither can stand in for the other, and a refresh is skipped when answering a challenge because it cannot produce the acrs claim being asked for.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8 +/- ##
==========================================
+ Coverage 96.57% 96.98% +0.41%
==========================================
Files 7 7
Lines 496 531 +35
==========================================
+ Hits 479 515 +36
+ Misses 17 16 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The retry brought in a handful of branches nothing exercised: the way a client reaches back to the authenticator, a retry that cannot reach Graph, and a reply that stops partway through, which had gone untested while it lived inline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A role whose PIM policy sits behind a Conditional Access authentication context
is refused at activation time: Graph answers with status 400 and
RoleAssignmentRequestAcrsValidationFailed, and buries a claims challenge inthe message as a URL-encoded query fragment (
&claims=...) naming the contextit wants.
The challenge asks for a token carrying the
acrsclaim, which is only issuedwhen the sign-in itself asked for the context. azpim discarded it, so such a
role could not be activated at all — signing in again produced the same token
and the same refusal.
Change
Error.ClaimsChallenge()digs the challenge out of the message it is buriedin, and only when it decodes to an actual claims document, so a message that
merely mentions the word does not open a browser.
Client.doanswers a challenge by re-acquiring the token and sending the samerequest once more. It lives there because any PIM call can be challenged and
the retry has to be the request that was refused, not one rebuilt from
scratch. A second refusal is returned as it came back.
Authenticator.TokenWithClaimspasses the claims to the authorizationrequest. A refresh cannot produce the
acrsclaim, so a challenge goesstraight to the browser instead of trying silently first.
plain call and the plain one is not handed back to the challenge that just
refused it. A second activation within the token's life opens no browser.
The claims are never sent unprompted: which contexts exist and which roles
require them is a per-tenant setting, so asking for one would fail in a tenant
that has not defined it and prompt for nothing in one that has. The value is
echoed back as the tenant wrote it rather than hardcoded.
Tests
Covers the retry and its token swap, an unchanged retry body, a challenge with
no way to answer it, one still refused afterwards, an abandoned sign-in, a
message that only mentions claims, the claims reaching the authorize request,
an ordinary sign-in not carrying them, the separate cache entry, and the
skipped refresh.