protected async Task <string> AppendScope(string scope, string filterTo) { // REF: https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens if (AuthCodeReceiver != null) { var scopes = await AuthCodeReceiver.GetAllScopes(); foreach (var s in scopes) { if (s.Contains(filterTo)) { scope += $" {s}"; } } } return(scope); }
public override async Task Token(HttpContext context) { // read flow, verify state and nonce if (!context.Request.Cookies.ContainsKey("authflow")) { throw new CasHttpException(400, "authflow not provided"); } var flow = JsonConvert.DeserializeObject <CasAuthFlow>(context.Request.Cookies["authflow"]); if (context.Request.Form["state"] != flow.state) { throw new CasHttpException(400, "state does not match"); } // throw error if one was returned if (context.Request.Form.ContainsKey("error_description")) { throw new CasHttpException(401, context.Request.Form["error_description"]); } // verify the id token string idRaw = context.Request.Form["id_token"]; var idToken = await VerifyTokenFromAAD(idRaw, CasConfig.AzureClientId, flow.nonce); // ICasAuthCodeReceiver: use the code to get an access token if (AuthCodeReceiver != null) { // get code string code = context.Request.Form["code"]; Tokens last = null; // get tokens for each scope var scopes = await AuthCodeReceiver.GetAllScopes(); foreach (var scope in scopes) { if (last == null) { last = await GetAccessTokenFromAuthCode(context, code, "offline_access " + scope); } else { last = await GetAccessTokenFromRefreshToken(last.refresh_token, "offline_access " + scope); } await AuthCodeReceiver.ReceiveAll(scope, last.access_token, last.refresh_token); break; } } // populate the claims from the id_token var claims = BuildClaims(idToken); // get the oid var oid = await GetOid(idToken, claims); // add a sub (useful for istio) var sub = claims.FirstOrDefault(c => c.Type == "email") ?? claims.FirstOrDefault(c => c.Type == "oid") ?? idToken.Payload.Claims.FirstOrDefault(c => c.Type == "sub"); if (sub != null) { claims.Add(new Claim("sub", sub.Value)); } // attempt to propogate roles var roles = idToken.Payload.Claims.Where(c => c.Type == "roles"); foreach (var role in roles) { claims.Add(new Claim("role", role.Value)); } // populate all application roles from the graph if (oid != null) { var assignments = await GetRoleAssignments(oid); foreach (var assignment in assignments) { foreach (var role in assignment.Roles) { claims.Add(new Claim(assignment.AppId + "-role", role)); } } } // apply custom claims if (ClaimsBuilder != null) { await ClaimsBuilder.AddAllClaims(idToken.Payload.Claims, claims); } // wrote the cookies await WriteTokenCookies(context, claims); // redirect await Redirect(context, flow); }