Example #1
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, Route = null)] HttpRequest req,
            ILogger log)
        {
            string errorMessage = string.Empty;

            var deviceId         = req.Headers["deviceid"].ToString().ToLowerInvariant();        // Device id, either a MAC address or a random string per session
            var userName         = req.Headers["username"].ToString().ToLowerInvariant();        // Username as registered in choosen authernication service (e.g. AAD userPrincipalName, GitHub username)
            var team             = req.Headers["teamname"].ToString().ToLowerInvariant();        // Teamname - id or name of the target group or team. Must be group id for AAD, team id for GitHub
            var company          = req.Headers["companyname"].ToString().ToLowerInvariant();     // Company name or tenant id. Must be tenant id for AAD, company id for GitHub
            var authServiceToken = req.Headers["authservicetoken"].ToString();                   // Authentication token received from authentication service. Bearer token for AAD or GitHub.
            var authService      = req.Headers["authservicename"].ToString().ToLowerInvariant(); // Authentication sercvice name. "graph.microsoft.com" for AAD, "github.com" for GitHub

            var             provider   = GraphServiceFactory.GetGraphService(authService);
            GraphAuthStatus authStatus = GraphAuthStatus.Unauthorized;

            if (provider == null)
            {
                errorMessage = $"{authService} is not a valid graph service name.";
            }
            else
            {
                authStatus = await provider.IsGroupMember(userName, company, team, authServiceToken, log);
            }

            ObjectResult funcResult = null;
            string       userId     = string.Empty;

            if (authStatus == GraphAuthStatus.OK)
            {
                userId = SignalRGroupUtils.GetFullUserId(authService, company, team, userName, deviceId);
                userId = userId.ToLowerInvariant();

                ServiceUtils utils       = new ServiceUtils(ConfigUtils.GetSignalRConnection());
                var          hubName     = ConfigUtils.GetHubName();
                var          clientUrl   = $"{utils.Endpoint}/client/?hub={hubName}";
                var          clientToken = utils.GenerateAccessToken(clientUrl,
                                                                     userId,
                                                                     TimeSpan.FromMinutes(UInt64.Parse(ConfigUtils.GetAuthTokenLifetimeMinutes())));

                string serverTime = ((long)(DateTime.UtcNow - DateTime.UnixEpoch).TotalSeconds).ToString();
                string turnServersAuthorization = ConfigUtils.MakeTURNAuthToken(company);

                funcResult = new OkObjectResult(new string[] { userId, clientToken, clientUrl, serverTime, turnServersAuthorization });
            }
            else
            {
                if (string.IsNullOrEmpty(errorMessage))
                {
                    errorMessage = $"Graph verification failed. Reason: {authStatus}";
                }
            }

            if (!string.IsNullOrEmpty(errorMessage))
            {
                log.LogError(errorMessage);
            }
            else
            {
                log.LogInformation($"Successfully negotiated for {userName} as {userId}");
            }

            return(string.IsNullOrEmpty(errorMessage)
                ? (ActionResult)funcResult
                : new BadRequestObjectResult(new { message = errorMessage }));
        }
Example #2
0
        public async Task <GraphAuthStatus> IsGroupMember(string userName, string companyOrTenant, string groupOrTeam, string authToken, ILogger log = null)
        {
            if (string.IsNullOrEmpty(userName) ||
                string.IsNullOrEmpty(groupOrTeam) ||
                string.IsNullOrEmpty(authToken))
            {
                log.LogError($"Invalid userName, company or group name");
                return(GraphAuthStatus.InvalidName);
            }

            _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
            var tokenStatus = await IsUserAuthToken(_client, userName, companyOrTenant, log);

            if (tokenStatus != System.Net.HttpStatusCode.OK)
            {
                return(GraphServiceFactory.GraphAuthStatusFromHttp(tokenStatus));
            }

            // If group doesn't matter we only check authentication status in AAD tenant
            if (groupOrTeam == "*")
            {
                return(GraphAuthStatus.OK);
            }

            GraphAuthStatus resStatus = GraphAuthStatus.UnknownError;

            string json = JsonConvert.SerializeObject(new GroupMembershipRequest()
            {
                groupIds = new string[] { groupOrTeam }
            });

            using (var content = new StringContent(json, Encoding.UTF8, "application/json"))
            {
                using (var response = await _client.PostAsync("https://graph.microsoft.com/beta/me/checkMemberGroups", content))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        dynamic res = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
                        if (res.value.Count > 0)
                        {
                            resStatus = GraphAuthStatus.OK;
                        }
                        else
                        {
                            resStatus = GraphAuthStatus.NotMemberOfTargetGroup;
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.LogError($"Team membership check failed: {response.StatusCode} ({await response.Content.ReadAsStringAsync()})");
                        }

                        resStatus = GraphServiceFactory.GraphAuthStatusFromHttp(response.StatusCode);
                    }
                }
            }

            return(resStatus);
        }