Beispiel #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 }));
        }
Beispiel #2
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var          authToken  = req.Headers["authtoken"].ToString();
            ServiceUtils utils      = new ServiceUtils(ConfigUtils.GetSignalRConnection());
            string       userIdHash = string.Empty;
            string       userId     = string.Empty;

            if (!utils.ParseAndValidateToken(authToken, out userIdHash, out userId, null))
            {
                log.LogError($"GetMessageToken: Invalid authentication token ({authToken})");
                return(new BadRequestObjectResult("Invalid authentication token"));
            }

            TimeSpan messageTokenLifetime = TimeSpan.FromMinutes(UInt64.Parse(ConfigUtils.GetAuthTokenLifetimeMinutes()));
            var      messageToken         = utils.GenerateAccessToken(utils.Endpoint,
                                                                      userId,
                                                                      messageTokenLifetime);

            string errorMessage = string.Empty;
            string userName;
            string company;
            string team;
            string authService;
            string deviceId;

            SignalRGroupUtils.ParseUserId(userId, out userName, out deviceId, out company, out team, out authService);

            var hubName = ConfigUtils.GetHubName();
            var groups  = SignalRGroupUtils.GetUserGroups(authService, company, team, userName, deviceId);

            foreach (var group in groups)
            {
                var groupHash = SignalRGroupUtils.GetNameHash(group, utils.AccessKey);

                var url          = $"{utils.Endpoint}/api/v1/hubs/{hubName}/groups/{groupHash}/users/{userIdHash}";
                var requestToken = utils.GenerateAccessToken(url, userId, TimeSpan.FromMinutes(1));

                using (var request = new HttpRequestMessage(HttpMethod.Put, url))
                {
                    request.Version = System.Net.HttpVersion.Version20;
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", requestToken);
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    using (var httpResult = await SignalRHttpClient.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
                    {
                        if (!httpResult.IsSuccessStatusCode)
                        {
                            var body = await httpResult.Content.ReadAsStringAsync();

                            errorMessage = $"Cannot add user {userId} ({userIdHash}) to group {group} ({groupHash}). Code: {httpResult.StatusCode}, Message: {httpResult.ReasonPhrase}, Body: {body}";
                            log.LogError(errorMessage);
                            break;
                        }
                    }
                }
            }

            return(string.IsNullOrEmpty(errorMessage)
                ? (ActionResult) new OkObjectResult(messageToken)
                : new BadRequestObjectResult(new { message = errorMessage }));
        }