Пример #1
0
        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);
        }
Пример #2
0
        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);
        }