|
| 1 | +title IdP calls a private Local Key Helper |
| 2 | + |
| 3 | +autonumber 1 |
| 4 | +participant "Relying Party" as W |
| 5 | +participant "IdP" as I |
| 6 | +participant "Browser" as B |
| 7 | +participant "Local Key Helper" as P |
| 8 | + |
| 9 | +note over W, P: IdP life... |
| 10 | +B->>I: Any request |
| 11 | +I->>B: Any response\nSec-Session-HelperIdList: [HelperId1, HelperId2], HelperCacheTime |
| 12 | +B->>B: Cache HelperId for IDPURL for HelperCacheTime |
| 13 | + |
| 14 | +note over W, P: Sign in... |
| 15 | +W->>B: Start sign in (302)\nSec-Session-Registration: path, RPChallenge,... \nSec-Session-GenerateKey: RPURL, IDPURL, extraParams |
| 16 | +B->>B: Check for cached HelperId for IDPURL |
| 17 | + |
| 18 | +alt Cached HelperId present (99.99% cases) |
| 19 | + |
| 20 | + B->>B: currentHelperId = Evaluate policy for (IdP, [HelperId1, HelperId2...]) |
| 21 | + |
| 22 | + B->>P: Pre-gen key and attest (RPURL, IDPURL, extraParams...) |
| 23 | + |
| 24 | + P->>P: Generate Key |
| 25 | + |
| 26 | + loop For each device |
| 27 | + P->>P: create binding statement S(publicKey, AIK) |
| 28 | + end |
| 29 | + |
| 30 | + P->>B: Return: KeyId, \narray of binding statements [BindingStatement1 {extraClaims....}, \nBindingStatement2 {extraCalims...}] |
| 31 | + B->>B: Remember this key is for RP (and maybe path) |
| 32 | + |
| 33 | + B->>I: Load sign-in (follow the 302)\n\nx-ms-RefreshTokenCredential1{nonce}\nx-ms-DeviceCredential1{nonce}\nx-ms-RefreshTokenCredential2{nonce}\nx-ms-DeviceCredential2{nonce} ...\n\nSec-Session-BindingInfo: KeyId, PublicKey, \narray of binding statements [BindingStatement1 {extraClaims....}, \nBindingStatement2 {extraCalims...}] |
| 34 | + |
| 35 | + opt nonce is stale |
| 36 | + I->>B: 302 to IdP with qs parameter sso_nonce=new_nonce\nSec-Session-GenerateKey: RPURL, IDPURL, extraParams |
| 37 | + B->>I: Load sign-in\n\nx-ms-RefreshTokenCredential1{new_nonce}\nx-ms-DeviceCredential1{new_nonce}\nx-ms-RefreshTokenCredential2{new_nonce}\nx-ms-DeviceCredential2{new_nonce} ...\n\nSec-Session-BindingInfo: KeyId, PublicKey, \narray of binding statements [BindingStatement1 {extraClaims....}, \nBindingStatement2 {extraCalims...}] |
| 38 | + end |
| 39 | + |
| 40 | +else No cached HelperId present |
| 41 | + |
| 42 | + |
| 43 | + B->>I: Load sign-in (follow the 302)\n\nx-ms-RefreshTokenCredential1{nonce}\nx-ms-DeviceCredential1{nonce}\nx-ms-RefreshTokenCredential2{nonce}\nx-ms-DeviceCredential2{nonce} ... \n\nSec-Session-HelperDiscoveryNeeded: RPURL, IDPURL, extraParams |
| 44 | + |
| 45 | + note over I, B: No binding info present, but the reequest has GenerratKey, so IdP issues helper id list |
| 46 | + |
| 47 | + I->>B: 302 to IdP with qs parameter sso_nonce=new_nonce\n\nSec-Session-GenerateKey: RPURL, IDPURL, extraParams\nSec-Session-HelperIdList: [HelperId1, HelperId2], HelperCacheTime |
| 48 | + B->>B: Cache HelperId for IDPURL for HelperCacheTime |
| 49 | + |
| 50 | + B->>B: currentHelperId = Evaluate policy for (IdP, [HelperId1]) |
| 51 | + B->>P: Pre-gen key and attest (RPURL, IDPURL, extraParams...) |
| 52 | + |
| 53 | + P->>P: Generate Key |
| 54 | + |
| 55 | + loop For each device |
| 56 | + P->>P: create binding statement S(publicKey, AIK) |
| 57 | + end |
| 58 | + |
| 59 | + P->>B: Return: KeyId, \narray of binding statements [BindingStatement1 {extraClaims....}, \nBindingStatement2 {extraCalims...}] |
| 60 | + B->>B: Remember this key is for RP (and maybe path) |
| 61 | + |
| 62 | + B->>I: Load sign-in\n\nx-ms-RefreshTokenCredential1{new_nonce}\nx-ms-DeviceCredential1{new_nonce}\n x-ms-RefreshTokenCredential2{new_nonce}\n x-ms-DeviceCredential2{new_nonce} ... \n\nSec-Session-BindingInfo: KeyId, PublicKey, \narray of binding statements [BindingStatement1 {extraClaims....}, \nBindingStatement2 {extraCalims...}] |
| 63 | + |
| 64 | + |
| 65 | +end |
| 66 | + |
| 67 | +opt SSO information is not sufficient |
| 68 | + I->>B: Sign in ceremony |
| 69 | + B->>I: Sign done |
| 70 | +end |
| 71 | + |
| 72 | +I->>B: Authorization code, KeyId |
| 73 | + |
| 74 | + |
| 75 | +note over W, B: Since DBSC session has been initialized already for RP, browser needs to generate JWT on redirect back |
| 76 | +B->>P: Request Sign JWT (path, RPChallenge, extraParams) |
| 77 | +P->>B: Return JWT Signature |
| 78 | +note over W, B: JWT is appended by the browser before returning the response from IDP back to the RP |
| 79 | +B->>W: Authorization code, KeyId, JWT |
| 80 | +W->>I: (confidential client request) redeem authorization code |
| 81 | +I->>W: (confidential client response) return id_token |
| 82 | +W->>W: parse id_token and validate binding, match with the JWT from the previous |
| 83 | +W->>B: Bound AuthCookie |
| 84 | + |
| 85 | +note over W, P: Refresh DBSC... |
| 86 | +B->>W: GET /securesession/refresh (sessionID) |
| 87 | +W->>B: Challenge, **extraParams** |
| 88 | +B->>P: Request Sign JWT (sessionID, RPChallenge, **extraParams**) |
| 89 | +P->>B: Return JWT Signature |
| 90 | +B->>W: GET /securesession/refresh (JWT) |
| 91 | +W->>W: Validate JWT (w/public key on file) |
| 92 | +W->>B: AuthCookie |
0 commit comments