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 })); }
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 })); }