public async void Emulator_MsaHeader_BotAppIdDiffers_ShouldNotValidate() { string header = $"Bearer {await new MicrosoftAppCredentials("2cd87869-38a0-4182-9251-d056e8f0ac24", "2.30Vs3VQLKt974F").GetTokenAsync()}"; var credentials = new SimpleCredentialProvider("00000000-0000-0000-0000-000000000000", ""); await Assert.ThrowsAsync <UnauthorizedAccessException>( async() => await JwtTokenValidation.ValidateAuthHeader(header, credentials, "", null, emptyClient)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { if (await Options.CredentialProvider.IsAuthenticationDisabledAsync()) { var anonymousPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Bot") })); var anonynousContext = new TokenValidatedContext(Context, Scheme, Options) { Principal = anonymousPrincipal }; anonynousContext.Success(); return(anonynousContext.Result); } string authHeader = Request.Headers["Authorization"]; ClaimsIdentity claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, Options.CredentialProvider, _httpClient); Logger.TokenValidationSucceeded(); claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Bot")); var principal = new ClaimsPrincipal(claimsIdentity); Context.User = principal; string jwtToken = JwtTokenExtractor.ExtractBearerTokenFromAuthHeader(authHeader); var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options) { Principal = principal, SecurityToken = new JwtSecurityToken(jwtToken) }; await Events.TokenValidated(tokenValidatedContext); if (tokenValidatedContext.Result != null) { return(tokenValidatedContext.Result); } tokenValidatedContext.Success(); return(tokenValidatedContext.Result); } catch (Exception ex) { Logger.ErrorProcessingMessage(ex); var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options) { Exception = ex }; await Events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.Result != null) { return(authenticationFailedContext.Result); } throw; } }
public async Task <(bool IsAuthenticated, string ErrorMessage)> Validate(HttpRequest request) { if (!request.Headers.TryGetValue("Authorization", out StringValues authorizationHeader)) { return(false, "Missing 'Authorization' header"); } var credential = new SimpleCredentialProvider( _configuration.GetValue <string>("Bot:Id"), _configuration.GetValue <string>("Bot:Password")); try { var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authorizationHeader, credential, null, null); if (!claimsIdentity.IsAuthenticated) { return(false, "The request fails to pass auth check."); } } catch (Exception ex) { _logger.LogWarning(ex, "Failed to check authentication."); return(false, $"Failed to check authentication: {ex.Message}"); } return(true, string.Empty); }
public async void Emulator_MsaHeader_BotAppIdDiffers_ShouldNotValidate() { var header = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlNTUWRoSTFjS3ZoUUVEU0p4RTJnR1lzNDBRMCIsImtpZCI6IlNTUWRoSTFjS3ZoUUVEU0p4RTJnR1lzNDBRMCJ9.eyJhdWQiOiIzOTYxOWE1OS01YTBjLTRmOWItODdjNS04MTZjNjQ4ZmYzNTciLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9kNmQ0OTQyMC1mMzliLTRkZjctYTFkYy1kNTlhOTM1ODcxZGIvIiwiaWF0IjoxNTE4MTIzMTQxLCJuYmYiOjE1MTgxMjMxNDEsImV4cCI6MTUxODEyNzA0MSwiYWlvIjoiWTJOZ1lQZ1djOSsrenJvaW9QM28rZmw2OWR1c0FBPT0iLCJhcHBpZCI6IjM5NjE5YTU5LTVhMGMtNGY5Yi04N2M1LTgxNmM2NDhmZjM1NyIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2Q2ZDQ5NDIwLWYzOWItNGRmNy1hMWRjLWQ1OWE5MzU4NzFkYi8iLCJ0aWQiOiJkNmQ0OTQyMC1mMzliLTRkZjctYTFkYy1kNTlhOTM1ODcxZGIiLCJ1dGkiOiJPVXE3M1lSbGtFcVoxQ3p2U3FZQkFBIiwidmVyIjoiMS4wIn0.B0t4sSsqIQ3IT2rfpZXqAdAGJSr3aihwk-jJd8as2pAoeQVcQNir_Anvvnjbo5MsB0DCyWFa9xnEmBRiTW_Ww97Z9bZhnCXq4D4vN8dmgEMV_Aci1tI4agy3coCX4fBRc76SHjqJ_ucl850aqR3d_0sfl0TPoDclE4jWssX2YTNzUAMEgisbYe9xv8FfK7AUR8ABS1teTfnWGVYyVFgC7vptSjw-de8sgz7pv8vVtLEKBrrb1FBSzHbbnZ-cQaLLHeIM4agamXf4w45o7_1uHorrp1Tg5oPrsbiayC-dt4lpC9smU5agpyUWCorKZI0Fp3aryG4519cYuLyXuUVh0A"; var credentials = new SimpleCredentialProvider("00000000-0000-0000-0000-000000000000", ""); await Assert.ThrowsAsync <UnauthorizedAccessException>( async() => await JwtTokenValidation.ValidateAuthHeader(header, credentials, "")); }
public async void EmptyHeader_BotWithNoCredentials_ShouldValidate() { var header = ""; var credentials = new SimpleCredentialProvider("", ""); var result = await JwtTokenValidation.ValidateAuthHeader(header, credentials, ""); Assert.True(result.IsAuthenticated); }
public async void Connector_AuthHeader_BotAppIdDiffers_ShouldNotValidate() { var header = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkdDeEFyWG9OOFNxbzdQd2VBNy16NjVkZW5KUSIsIng1dCI6IkdDeEFyWG9OOFNxbzdQd2VBNy16NjVkZW5KUSJ9.eyJzZXJ2aWNldXJsIjoiaHR0cHM6Ly93ZWJjaGF0LmJvdGZyYW1ld29yay5jb20vIiwiaXNzIjoiaHR0cHM6Ly9hcGkuYm90ZnJhbWV3b3JrLmNvbSIsImF1ZCI6IjM5NjE5YTU5LTVhMGMtNGY5Yi04N2M1LTgxNmM2NDhmZjM1NyIsImV4cCI6MTUxNjczNzUyMCwibmJmIjoxNTE2NzM2OTIwfQ.TBgpxbDS-gx1wm7ldvl7To-igfskccNhp-rU1mxUMtGaDjnsU--usH4OXZfzRsZqMlnXWXug_Hgd_qOr5RH8wVlnXnMWewoZTSGZrfp8GOd7jHF13Gz3F1GCl8akc3jeK0Ppc8R_uInpuUKa0SopY0lwpDclCmvDlz4PN6yahHkt_666k-9UGmRt0DDkxuYjbuYG8EDZxyyAhr7J6sFh3yE2UGRpJjRDB4wXWqv08Cp0Gn9PAW2NxOyN8irFzZH5_YZqE3DXDAYZ_IOLpygXQR0O-bFIhLDVxSz6uCeTBRjh8GU7XJ_yNiRDoaby7Rd2IfRrSnvMkBRsB8MsWN8oXg"; var credentials = new SimpleCredentialProvider("00000000-0000-0000-0000-000000000000", ""); await Assert.ThrowsAsync <UnauthorizedAccessException>( async() => await JwtTokenValidation.ValidateAuthHeader(header, credentials, "https://webchat.botframework.com/")); }
public async void Connector_AuthHeader_CorrectAppIdAndServiceUrl_ShouldValidate() { var header = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkdDeEFyWG9OOFNxbzdQd2VBNy16NjVkZW5KUSIsIng1dCI6IkdDeEFyWG9OOFNxbzdQd2VBNy16NjVkZW5KUSJ9.eyJzZXJ2aWNldXJsIjoiaHR0cHM6Ly93ZWJjaGF0LmJvdGZyYW1ld29yay5jb20vIiwiaXNzIjoiaHR0cHM6Ly9hcGkuYm90ZnJhbWV3b3JrLmNvbSIsImF1ZCI6IjM5NjE5YTU5LTVhMGMtNGY5Yi04N2M1LTgxNmM2NDhmZjM1NyIsImV4cCI6MTUxNjczNzUyMCwibmJmIjoxNTE2NzM2OTIwfQ.TBgpxbDS-gx1wm7ldvl7To-igfskccNhp-rU1mxUMtGaDjnsU--usH4OXZfzRsZqMlnXWXug_Hgd_qOr5RH8wVlnXnMWewoZTSGZrfp8GOd7jHF13Gz3F1GCl8akc3jeK0Ppc8R_uInpuUKa0SopY0lwpDclCmvDlz4PN6yahHkt_666k-9UGmRt0DDkxuYjbuYG8EDZxyyAhr7J6sFh3yE2UGRpJjRDB4wXWqv08Cp0Gn9PAW2NxOyN8irFzZH5_YZqE3DXDAYZ_IOLpygXQR0O-bFIhLDVxSz6uCeTBRjh8GU7XJ_yNiRDoaby7Rd2IfRrSnvMkBRsB8MsWN8oXg"; var credentials = new SimpleCredentialProvider("39619a59-5a0c-4f9b-87c5-816c648ff357", ""); var result = await JwtTokenValidation.ValidateAuthHeader(header, credentials, client); Assert.True(result.IsAuthenticated); }
public async void Emulator_MsaHeader_CorrectAppIdAndServiceUrl_ShouldValidate() { string header = $"Bearer {await new MicrosoftAppCredentials("2cd87869-38a0-4182-9251-d056e8f0ac24", "2.30Vs3VQLKt974F").GetTokenAsync()}"; var credentials = new SimpleCredentialProvider("2cd87869-38a0-4182-9251-d056e8f0ac24", ""); var result = await JwtTokenValidation.ValidateAuthHeader(header, credentials, "", "https://webchat.botframework.com/", emptyClient); Assert.True(result.IsAuthenticated); }
private async Task JwtTokenValidation_ValidateAuthHeader_WithChannelService_Succeeds(string header, string appId, string pwd, string channelService) { var credentials = new SimpleCredentialProvider(appId, pwd); var channel = new SimpleChannelProvider(channelService); var result = await JwtTokenValidation.ValidateAuthHeader(header, credentials, channel, string.Empty, "https://webchat.botframework.com/", client); Assert.True(result.IsAuthenticated); }
public async void EmptyHeader_BotWithNoCredentials_ShouldThrow() { var header = string.Empty; var credentials = new SimpleCredentialProvider(string.Empty, string.Empty); await Assert.ThrowsAsync <ArgumentNullException>( async() => await JwtTokenValidation.ValidateAuthHeader(header, credentials, new SimpleChannelProvider(), string.Empty, null, emptyClient)); }
public async void Connector_AuthHeader_BotWithNoCredentials_ShouldNotValidate() { // token received and auth disabled string header = $"Bearer {await new MicrosoftAppCredentials("2cd87869-38a0-4182-9251-d056e8f0ac24", "2.30Vs3VQLKt974F").GetTokenAsync()}"; var credentials = new SimpleCredentialProvider("", ""); await Assert.ThrowsAsync <UnauthorizedAccessException>( async() => await JwtTokenValidation.ValidateAuthHeader(header, credentials, "", null, client)); }
private async Task JwtTokenValidation_ValidateAuthHeader_WithChannelService_Throws(string header, string appId, string pwd, string channelService) { var credentials = new SimpleCredentialProvider(appId, pwd); var channel = new SimpleChannelProvider(channelService); await Assert.ThrowsAsync <UnauthorizedAccessException>( async() => await JwtTokenValidation.ValidateAuthHeader( header, credentials, channel, string.Empty, "https://webchat.botframework.com/", client)); }
/// <summary> /// Validates the auth header for WebSocket upgrade requests. /// </summary> /// <remarks> /// Returns a ClaimsIdentity for successful auth and when auth is disabled. Returns null for failed auth. /// </remarks> /// <param name="httpRequest">The connection request.</param> private async Task <ClaimsIdentity> AuthenticateRequestAsync(HttpRequest httpRequest) { try { if (!await CredentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false)) { var authHeader = httpRequest.Headers.First(x => string.Equals(x.Key, AuthHeaderName, StringComparison.OrdinalIgnoreCase)).Value.FirstOrDefault(); var channelId = httpRequest.Headers.First(x => string.Equals(x.Key, ChannelIdHeaderName, StringComparison.OrdinalIgnoreCase)).Value.FirstOrDefault(); if (string.IsNullOrWhiteSpace(authHeader)) { await WriteUnauthorizedResponseAsync(AuthHeaderName, httpRequest).ConfigureAwait(false); return(null); } if (string.IsNullOrWhiteSpace(channelId)) { await WriteUnauthorizedResponseAsync(ChannelIdHeaderName, httpRequest).ConfigureAwait(false); return(null); } var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, CredentialProvider, ChannelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return(null); } // Add ServiceURL to the cache of trusted sites in order to allow token refreshing. AppCredentials.TrustServiceUrl(claimsIdentity.FindFirst(AuthenticationConstants.ServiceUrlClaim).Value); ClaimsIdentity = claimsIdentity; return(claimsIdentity); } // Authentication is not enabled, therefore return an anonymous ClaimsIdentity. return(new ClaimsIdentity(new List <Claim>(), "anonymous")); } catch (Exception) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; await httpRequest.HttpContext.Response.WriteAsync("Error while attempting to authorize connection.").ConfigureAwait(false); throw; } }
private async Task <bool> AuthenticateRequestAsync(HttpRequest httpRequest) { try { if (!await CredentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false)) { var authHeader = httpRequest.Headers.First(x => x.Key.ToLower() == AuthHeaderName).Value.FirstOrDefault(); var channelId = httpRequest.Headers.First(x => x.Key.ToLower() == ChannelIdHeaderName).Value.FirstOrDefault(); if (string.IsNullOrWhiteSpace(authHeader)) { await WriteUnauthorizedResponseAsync(AuthHeaderName, httpRequest).ConfigureAwait(false); return(false); } if (string.IsNullOrWhiteSpace(channelId)) { await WriteUnauthorizedResponseAsync(ChannelIdHeaderName, httpRequest).ConfigureAwait(false); return(false); } var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, CredentialProvider, ChannelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return(false); } // Add ServiceURL to the cache of trusted sites in order to allow token refreshing. AppCredentials.TrustServiceUrl(claimsIdentity.FindFirst(AuthenticationConstants.ServiceUrlClaim).Value); ClaimsIdentity = claimsIdentity; } return(true); } catch (Exception ex) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; await httpRequest.HttpContext.Response.WriteAsync("Error while attempting to authorize connection.").ConfigureAwait(false); throw ex; } }
public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken = default(CancellationToken)) { if (httpRequest == null) { throw new ArgumentNullException(nameof(httpRequest)); } if (httpResponse == null) { throw new ArgumentNullException(nameof(httpResponse)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } var authHeader = httpRequest.Headers["Authorization"]; var channelId = httpRequest.Headers["ChannelId"]; try { var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialProvider, _channelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return; } } catch (Exception) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return; } if (!httpRequest.HttpContext.WebSockets.IsWebSocketRequest) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; await httpRequest.HttpContext.Response.WriteAsync("Upgrade to WebSocket required.").ConfigureAwait(false); return; } await CreateWebSocketConnectionAsync(httpRequest.HttpContext, authHeader, channelId, bot).ConfigureAwait(false); }
private async Task <bool> AuthenticateRequestAsync(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse) { try { if (!await CredentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false)) { #pragma warning disable CA1308 // Normalize strings to uppercase (header names come in lowercase, ignoring) var authHeader = httpRequest.Headers.GetValues(AuthHeaderName.ToLowerInvariant()).FirstOrDefault(); var channelId = httpRequest.Headers.GetValues(ChannelIdHeaderName.ToLowerInvariant()).FirstOrDefault(); #pragma warning restore CA1308 // Normalize strings to uppercase if (string.IsNullOrWhiteSpace(authHeader)) { WriteUnauthorizedResponse(AuthHeaderName, httpResponse); return(false); } if (string.IsNullOrWhiteSpace(channelId)) { WriteUnauthorizedResponse(ChannelIdHeaderName, httpResponse); return(false); } var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, CredentialProvider, ChannelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpResponse.StatusCode = HttpStatusCode.Unauthorized; return(false); } // Add ServiceURL to the cache of trusted sites in order to allow token refreshing. AppCredentials.TrustServiceUrl(claimsIdentity.FindFirst(AuthenticationConstants.ServiceUrlClaim).Value); ClaimsIdentity = claimsIdentity; } return(true); } catch (Exception) { httpResponse.StatusCode = HttpStatusCode.InternalServerError; httpResponse.Content = new StringContent("Error while attempting to authorize connection."); throw; } }
public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken = default) { if (httpRequest == null) { throw new ArgumentNullException(nameof(httpRequest)); } if (httpResponse == null) { throw new ArgumentNullException(nameof(httpResponse)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } object result = null; var statusCode = (int)HttpStatusCode.OK; try { // grab the auth header from the inbound http request var authHeader = httpRequest.Headers["Authorization"]; var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialsProvider, _channelProvider, "unknown").ConfigureAwait(false); var route = GetRoute(httpRequest); if (route == null) { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; return; } // Execute the route action result = await route.Action.Invoke(_skillAdapter, bot, claimsIdentity, httpRequest, route.Parameters, cancellationToken).ConfigureAwait(false); } catch (UnauthorizedAccessException) { // handle unauthorized here as this layer creates the http response statusCode = (int)HttpStatusCode.Unauthorized; } HttpHelper.WriteResponse(httpResponse, statusCode, result); }
private async Task <ClaimsIdentity> AuthenticateAsync(string authHeader) { if (string.IsNullOrWhiteSpace(authHeader)) { var isAuthDisabled = await _credentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false); if (isAuthDisabled) { // In the scenario where auth is disabled, we still want to have the // IsAuthenticated flag set in the ClaimsIdentity. To do this requires // adding in an empty claim. return(new ClaimsIdentity(new List <Claim>(), "anonymous")); } // No auth header. Auth is required. Request is not authorized. throw new UnauthorizedAccessException(); } return(await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialProvider, _channelProvider, "unknown", _authConfiguration).ConfigureAwait(false)); }
private async Task <bool> AuthenticateRequestAsync(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse) { try { if (!await CredentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false)) { var authHeader = httpRequest.Headers.GetValues(AuthHeaderName.ToLowerInvariant()).FirstOrDefault(); var channelId = httpRequest.Headers.GetValues(ChannelIdHeaderName.ToLowerInvariant()).FirstOrDefault(); if (string.IsNullOrWhiteSpace(authHeader)) { WriteUnauthorizedResponse(AuthHeaderName, httpResponse); return(false); } if (string.IsNullOrWhiteSpace(channelId)) { WriteUnauthorizedResponse(ChannelIdHeaderName, httpResponse); return(false); } var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, CredentialProvider, ChannelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpResponse.StatusCode = HttpStatusCode.Unauthorized; return(false); } ClaimsIdentity = claimsIdentity; } return(true); } catch (Exception) { httpResponse.StatusCode = HttpStatusCode.InternalServerError; httpResponse.Content = new StringContent("Error while attempting to authorize connection."); throw; } }
/// <summary> /// Helper to authenticate the header. /// </summary> /// <remarks> /// This code is very similar to the code in <see cref="JwtTokenValidation.AuthenticateRequest(IActivity, string, ICredentialProvider, IChannelProvider, AuthenticationConfiguration, HttpClient)"/>, /// we should move this code somewhere in that library when we refactor auth, for now we keep it private to avoid adding more public static /// functions that we will need to deprecate later. /// </remarks> /// <param name="authHeader">The auth header containing JWT token.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A <see cref="ClaimsIdentity"/> representing the claims associated with given header.</returns> internal override async Task <ClaimsIdentity> AuthenticateAsync(string authHeader, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(authHeader)) { var isAuthDisabled = await _credentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false); if (!isAuthDisabled) { // No auth header. Auth is required. Request is not authorized. throw new UnauthorizedAccessException(); } // In the scenario where auth is disabled, we still want to have the // IsAuthenticated flag set in the ClaimsIdentity. // To do this requires adding in an empty claim. // Since ChannelServiceHandler calls are always a skill callback call, we set the skill claim too. return(SkillValidation.CreateAnonymousSkillClaim()); } // Validate the header and extract claims. return(await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialProvider, ChannelProvider, "unknown", _authConfiguration).ConfigureAwait(false)); }
/// <summary> /// Process the initial request to establish a long lived connection via a streaming server. /// </summary> /// <param name="onTurnError"> The function to execute on turn errors.</param> /// <param name="middlewareSet">The set of middleware to perform on each turn.</param> /// <param name="httpRequest">The connection request.</param> /// <param name="httpResponse">The response sent on error or connection termination.</param> /// <param name="cancellationToken">Optional cancellation token.</param> /// <returns>Returns on task completion.</returns> internal async Task ProcessAsync(Func <ITurnContext, Exception, Task> onTurnError, List <Builder.IMiddleware> middlewareSet, HttpRequest httpRequest, HttpResponse httpResponse, CancellationToken cancellationToken = default(CancellationToken)) { if (httpRequest == null) { throw new ArgumentNullException(nameof(httpRequest)); } if (httpResponse == null) { throw new ArgumentNullException(nameof(httpResponse)); } if (!httpRequest.HttpContext.WebSockets.IsWebSocketRequest) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; await httpRequest.HttpContext.Response.WriteAsync("Upgrade to WebSocket is required.").ConfigureAwait(false); return; } try { if (!await _credentialProvider.IsAuthenticationDisabledAsync().ConfigureAwait(false)) { var authHeader = httpRequest.Headers.Where(x => x.Key.ToLower() == AuthHeaderName).FirstOrDefault().Value.FirstOrDefault(); var channelId = httpRequest.Headers.Where(x => x.Key.ToLower() == ChannelIdHeaderName).FirstOrDefault().Value.FirstOrDefault(); if (string.IsNullOrWhiteSpace(authHeader)) { await MissingAuthHeaderHelperAsync(AuthHeaderName, httpRequest).ConfigureAwait(false); return; } if (string.IsNullOrWhiteSpace(channelId)) { await MissingAuthHeaderHelperAsync(ChannelIdHeaderName, httpRequest).ConfigureAwait(false); return; } var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialProvider, _channelProvider, channelId).ConfigureAwait(false); if (!claimsIdentity.IsAuthenticated) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return; } } } catch (Exception ex) { httpRequest.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; await httpRequest.HttpContext.Response.WriteAsync("Error while attempting to authorize connection.").ConfigureAwait(false); throw ex; } await CreateStreamingServerConnectionAsync(onTurnError, middlewareSet, httpRequest.HttpContext).ConfigureAwait(false); }
private async Task <ClaimsIdentity> AuthenticateAsync(string authHeader) { return(await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialProvider, _channelProvider, "unknown", _authConfiguration).ConfigureAwait(false)); }
public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken = default) { if (httpRequest == null) { throw new ArgumentNullException(nameof(httpRequest)); } if (httpResponse == null) { throw new ArgumentNullException(nameof(httpResponse)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } var route = GetRoute(httpRequest); if (route == null) { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; return; } object result = null; var statusCode = (int)HttpStatusCode.OK; try { // grab the auth header from the inbound http request var authHeader = httpRequest.Headers["Authorization"]; var claimsIdentity = await JwtTokenValidation.ValidateAuthHeader(authHeader, _credentialsProvider, _channelProvider, "unknown").ConfigureAwait(false); switch (route.Method) { // [Route("/v3/conversations")] case ChannelApiMethods.CreateConversation: var parameters = HttpHelper.ReadRequest <ConversationParameters>(httpRequest); result = await _skillAdapter.CreateConversationAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, parameters, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities/{activityId}")] case ChannelApiMethods.DeleteActivity: // TODO: ask Tom why we use the value from the route and not from the activity here. await _skillAdapter.DeleteActivityAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, route.Parameters["activityId"].Value, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/members/{memberId}")] case ChannelApiMethods.DeleteConversationMember: await _skillAdapter.DeleteConversationMemberAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, route.Parameters["memberId"].Value, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities/{activityId}/members")] case ChannelApiMethods.GetActivityMembers: result = await _skillAdapter.GetActivityMembersAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, route.Parameters["activityId"].Value, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/members")] case ChannelApiMethods.GetConversationMembers: result = await _skillAdapter.GetConversationMembersAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/pagedmembers")] case ChannelApiMethods.GetConversationPagedMembers: var pageSize = string.IsNullOrWhiteSpace(route.Parameters["pageSize"].Value) ? -1 : int.Parse(route.Parameters["pageSize"].Value, CultureInfo.InvariantCulture); result = await _skillAdapter.GetConversationPagedMembersAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, pageSize, route.Parameters["continuationToken"].Value, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations")] case ChannelApiMethods.GetConversations: result = await _skillAdapter.GetConversationsAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, cancellationToken : cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities/{activityId}")] case ChannelApiMethods.ReplyToActivity: var replyToActivity = HttpHelper.ReadRequest <Activity>(httpRequest); result = await _skillAdapter.ReplyToActivityAsync(bot, claimsIdentity, replyToActivity.Conversation.Id, route.Parameters["activityId"].Value, replyToActivity, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities/history")] case ChannelApiMethods.SendConversationHistory: var history = HttpHelper.ReadRequest <Transcript>(httpRequest); result = await _skillAdapter.SendConversationHistoryAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, history, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities")] case ChannelApiMethods.SendToConversation: var sendToConversationActivity = HttpHelper.ReadRequest <Activity>(httpRequest); result = await _skillAdapter.SendToConversationAsync(bot, claimsIdentity, sendToConversationActivity.Conversation.Id, sendToConversationActivity, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/activities/{activityId}")] case ChannelApiMethods.UpdateActivity: var updateActivity = HttpHelper.ReadRequest <Activity>(httpRequest); result = await _skillAdapter.UpdateActivityAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, route.Parameters["activityId"].Value, updateActivity, cancellationToken).ConfigureAwait(false); break; // [Route("/v3/conversations/{conversationId}/attachments")] case ChannelApiMethods.UploadAttachment: var uploadAttachment = HttpHelper.ReadRequest <AttachmentData>(httpRequest); result = await _skillAdapter.UploadAttachmentAsync(bot, claimsIdentity, route.Parameters["conversationId"].Value, uploadAttachment, cancellationToken).ConfigureAwait(false); break; default: httpResponse.StatusCode = (int)HttpStatusCode.NotFound; return; } } catch (UnauthorizedAccessException) { // handle unauthorized here as this layer creates the http response statusCode = (int)HttpStatusCode.Unauthorized; } HttpHelper.WriteResponse(httpResponse, statusCode, result); }