public void ValidateAuthState_InvalidState(long timestamp, string redirectUrl, long identityProviderId, long tenantId, string nonce) { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); // Create invalid auth state var authState = new OpenIdConnectAuthorizationState { Timestamp = timestamp, RedirectUrl = redirectUrl, IdentityProviderId = identityProviderId, TenantId = tenantId, Nonce = nonce }; // Serialize and encrypt state var stateJson = JSON.Serialize(authState); var cryptoProvider = new EncodingCryptoProvider(); var encryptedState = cryptoProvider.EncryptAndEncode(stateJson); Assert.That( () => oidcLoginHandler.ValidateAuthState(encryptedState), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has invalid data.")); }
public void GetAuthorizationCodeRequestUrl_InvalidProviderSetup(string clientId, string clientSecret, string configUrl, string claim, bool enabled) { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); var provider = new OidcIdentityProvider { Name = "ID Provider " + Guid.NewGuid(), IsProviderEnabled = enabled, OidcClientId = clientId, OidcClientSecret = clientSecret, OidcIdentityProviderConfigurationUrl = configUrl, OidcUserIdentityClaim = claim }; Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl( new IdentityProviderLoginRequest { IdentityProviderId = provider.Id, Tenant = "EDC", RedirectUrl = "http://test.com" }, new Uri("http://test.com")), Throws.TypeOf <AuthenticationException>()); }
public void ProcessOidcAuthorizationResponse_InvalidProviderSetup(string clientId, string clientSecret, string configUrl, string claim, bool enabled) { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); string tenantName = GetCurrentTenantName(); var provider = new OidcIdentityProvider { Name = "ID Provider " + Guid.NewGuid(), IsProviderEnabled = enabled, OidcClientId = clientId, OidcClientSecret = clientSecret, OidcIdentityProviderConfigurationUrl = configUrl, OidcUserIdentityClaim = claim }; var authState = new OpenIdConnectAuthorizationState { TenantId = RequestContext.TenantId, IdentityProviderId = provider.Id }; Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, "code", authState, new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <AuthenticationException>()); }
public void ProcessOidcAuthorizationResponse_InvalidAuthState() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); string tenantName = GetCurrentTenantName(); var authState1 = new OpenIdConnectAuthorizationState { TenantId = RequestContext.TenantId, Timestamp = DateTime.UtcNow.Ticks, IdentityProviderId = 1000, Nonce = "xx", RedirectUrl = "http://test.com" }; Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, "code", authState1, new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The identity provider does not exist.")); var authState2 = new OpenIdConnectAuthorizationState { TenantId = 100, Timestamp = DateTime.UtcNow.Ticks, IdentityProviderId = 1000, Nonce = "xx", RedirectUrl = "http://test.com" }; Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, "code", authState2, new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The tenant is invalid.")); }
public async Task <IHttpActionResult> GetIdentityProviderAuthorizeUrl([FromBody] IdentityProviderLoginRequest idpLoginRequest) { if (idpLoginRequest == null) { throw new WebArgumentException("idpLoginRequest", "The identity provider login request is invalid."); } var oidcLoginHandler = new OpenIdConnectLoginHandler(OpenIdConnectConfigurationManager); if (oidcLoginHandler.IsTokenValidationDisabled) { EventLog.Application.WriteError("OpenIdConnectLoginHandler has token validation disabled. This is not be used in production."); throw new AuthenticationException(); } try { var authorizeUrl = await oidcLoginHandler.GetAuthorizationCodeRequestUrl(idpLoginRequest, new Uri(Request.RequestUri.GetLeftPart(UriPartial.Authority))); return(Ok(authorizeUrl.ToString())); } catch (Exception exception) { EventLog.Application.WriteError("Failed to get identity provider authorize url. Error: {0}", exception.ToString()); throw; } }
public void OpenIdConnectLoginHandlerConstructor() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); Assert.IsNotNull(oidcLoginHandler, "Handler should not be null"); }
public void ProcessOidcAuthorizationResponse_FailedTokenRequest(string response, HttpStatusCode httpStatusCode, Type exceptionType, string message) { var context = RequestContext.GetContext(); OidcIdentityProvider idProvider; OidcIdentityProviderUser idProviderUser; UserAccount userAccount; string tenantName = GetCurrentTenantName(); CreateEntityModel("*****@*****.**", true, out idProvider, out idProviderUser, out userAccount); var code = Guid.NewGuid().ToString(); // Mock config provider and http client var errorResponseMessage = new HttpResponseMessage { Content = new StringContent(response), StatusCode = httpStatusCode }; var mockRepo = new MockRepository(MockBehavior.Strict); var configUrl = idProvider.OidcIdentityProviderConfigurationUrl; var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); configManager.Setup(w => w.GetIdentityProviderConfigurationAsync(configUrl)).Returns(Task.FromResult(_oidcConfig)); configManager.Setup(w => w.RemoveIdentityProviderConfiguration(configUrl)); var httpClient = mockRepo.Create <IHttpClient>(); httpClient.Setup(w => w.PostAsync(new Uri(_oidcConfig.TokenEndpoint), It.IsAny <HttpContent>())) .Returns(Task.FromResult(errorResponseMessage)); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); var idpLoginRequest = new IdentityProviderLoginRequest { Tenant = context.Tenant.Name, IdentityProviderId = idProvider.Id, RedirectUrl = "https://test.com/login/callback" }; var baseUri = new Uri("https://test.com"); // Get code auth uri, get state var uri = Task.Run(() => oidcLoginHandler.GetAuthorizationCodeRequestUrl(idpLoginRequest, baseUri)).Result; var queryValues = uri.ParseQueryString(); var state = queryValues["state"]; var validatedState = oidcLoginHandler.ValidateAuthState(state); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, code, validatedState, baseUri, httpClient.Object), Throws.TypeOf(exceptionType).And.Message.EqualTo(message)); mockRepo.VerifyAll(); }
public void ValidateAuthState_CorruptState() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); Assert.That( () => oidcLoginHandler.ValidateAuthState("xx"), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state is invalid.")); }
public void ValidateAuthState_NullEmptyState() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); Assert.That( () => oidcLoginHandler.ValidateAuthState(null), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("state")); Assert.That( () => oidcLoginHandler.ValidateAuthState(string.Empty), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("state")); }
public void ValidateAuthState_ExpiredState() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); // Create invalid auth state var authState = new OpenIdConnectAuthorizationState { Timestamp = DateTime.UtcNow.AddHours(10).Ticks, RedirectUrl = "http://test.com", IdentityProviderId = 100, TenantId = 100, Nonce = "xx" }; // Serialize and encrypt state var stateJson = JSON.Serialize(authState); var cryptoProvider = new EncodingCryptoProvider(); var encryptedState1 = cryptoProvider.EncryptAndEncode(stateJson); Assert.That( () => oidcLoginHandler.ValidateAuthState(encryptedState1), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has expired.")); // Create invalid auth state authState = new OpenIdConnectAuthorizationState { Timestamp = DateTime.UtcNow.AddHours(-10).Ticks, RedirectUrl = "http://test.com", IdentityProviderId = 100, TenantId = 100, Nonce = "xx" }; // Serialize and encrypt state stateJson = JSON.Serialize(authState); cryptoProvider = new EncodingCryptoProvider(); var encryptedState2 = cryptoProvider.EncryptAndEncode(stateJson); Assert.That( () => oidcLoginHandler.ValidateAuthState(encryptedState2), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has expired.")); }
public void ProcessOidcAuthorizationResponse_InvalidParams() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(null, null, new OpenIdConnectAuthorizationState(), new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("tenant")); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse("EDC", null, new OpenIdConnectAuthorizationState(), new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("code")); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse("EDC", string.Empty, new OpenIdConnectAuthorizationState(), new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("code")); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse("EDC", "code", null, new Uri("http://test.com"), new BasicHttpClient()), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("authState")); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse("EDC", "code", new OpenIdConnectAuthorizationState(), null, new BasicHttpClient()), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("requestBaseUrl")); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse("EDC", "code", new OpenIdConnectAuthorizationState(), new Uri("http://test.com"), null), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("httpClient")); }
public void ProcessOidcAuthorizationResponse_InvalidUser(string test) { var context = RequestContext.GetContext(); OidcIdentityProvider idProvider = null; OidcIdentityProviderUser idProviderUser; UserAccount userAccount; string tenantName = GetCurrentTenantName(); switch (test) { case "NoIdpUser": // Create user account with a different name CreateEntityModel("testUser", true, out idProvider, out idProviderUser, out userAccount); break; case "NoUserAccount": // Create idp user with matching name but without associated account CreateEntityModelNoUserAccount("*****@*****.**", out idProvider, out idProviderUser); break; case "DisabledUserAccount": // Create user account with a disabled account CreateEntityModel("*****@*****.**", false, out idProvider, out idProviderUser, out userAccount); break; } var code = Guid.NewGuid().ToString(); // Mock config provider and http client var expectedTokenRequestMessage = new OpenIdConnectMessage { GrantType = "authorization_code", Code = code, ClientSecret = Factory.SecuredData.Read((Guid)idProvider.OidcClientSecretSecureId), ClientId = idProvider.OidcClientId, RedirectUri = "https://test.com/spapi/data/v1/login/oidc/authresponse/" + tenantName }; var validResponseMessage = new HttpResponseMessage { Content = new StringContent(_openIdTokenResponse) }; var mockRepo = new MockRepository(MockBehavior.Strict); var configUrl = idProvider.OidcIdentityProviderConfigurationUrl; var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); configManager.Setup(w => w.GetIdentityProviderConfigurationAsync(configUrl)).Returns(Task.FromResult(_oidcConfig)); var httpClient = mockRepo.Create <IHttpClient>(); httpClient.Setup(w => w.PostAsync(new Uri(_oidcConfig.TokenEndpoint), It.Is <HttpContent>(c => ValidateTokenRequestMessage(expectedTokenRequestMessage, c)))) .Returns(Task.FromResult(validResponseMessage)); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object, true); var idpLoginRequest = new IdentityProviderLoginRequest { Tenant = context.Tenant.Name, IdentityProviderId = idProvider.Id, RedirectUrl = "https://test.com/login/callback/" }; var baseUri = new Uri("https://test.com"); // Get code auth uri, get state var uri = Task.Run(() => oidcLoginHandler.GetAuthorizationCodeRequestUrl(idpLoginRequest, baseUri)).Result; var queryValues = uri.ParseQueryString(); var state = queryValues["state"]; var validatedState = oidcLoginHandler.ValidateAuthState(state); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, code, validatedState, baseUri, httpClient.Object), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The request context could not be found. The user name may be incorrect or the account may be locked, disabled or expired.")); mockRepo.VerifyAll(); }
public void ProcessOidcAuthorizationResponse_EnabledTokenValidation() { var context = RequestContext.GetContext(); OidcIdentityProvider idProvider; OidcIdentityProviderUser idProviderUser; UserAccount userAccount; string tenantName = GetCurrentTenantName(); CreateEntityModel("*****@*****.**", true, out idProvider, out idProviderUser, out userAccount); var code = Guid.NewGuid().ToString(); // Mock config provider and http client var expectedTokenRequestMessage = new OpenIdConnectMessage { GrantType = "authorization_code", Code = code, ClientSecret = Factory.SecuredData.Read((Guid)idProvider.OidcClientSecretSecureId), ClientId = idProvider.OidcClientId, RedirectUri = "https://test.com/spapi/data/v1/login/oidc/authresponse/" + tenantName }; var validResponseMessage = new HttpResponseMessage { Content = new StringContent(_openIdTokenResponse) }; var mockRepo = new MockRepository(MockBehavior.Strict); var configUrl = idProvider.OidcIdentityProviderConfigurationUrl; var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); configManager.Setup(w => w.GetIdentityProviderConfigurationAsync(configUrl)).Returns(Task.FromResult(_oidcConfig)); configManager.Setup(w => w.RemoveIdentityProviderConfiguration(configUrl)); var httpClient = mockRepo.Create <IHttpClient>(); httpClient.Setup(w => w.PostAsync(new Uri(_oidcConfig.TokenEndpoint), It.Is <HttpContent>(c => ValidateTokenRequestMessage(expectedTokenRequestMessage, c)))) .Returns(Task.FromResult(validResponseMessage)); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); var idpLoginRequest = new IdentityProviderLoginRequest { Tenant = context.Tenant.Name, IdentityProviderId = idProvider.Id, RedirectUrl = "https://test.com/login/callback" }; var baseUri = new Uri("https://test.com"); // Get code auth uri, get state var uri = Task.Run(() => oidcLoginHandler.GetAuthorizationCodeRequestUrl(idpLoginRequest, baseUri)).Result; var queryValues = uri.ParseQueryString(); var state = queryValues["state"]; var validatedState = oidcLoginHandler.ValidateAuthState(state); Assert.That( async() => await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenantName, code, validatedState, baseUri, httpClient.Object), Throws.TypeOf <AuthenticationException>()); }
public void GetAuthorizationCodeRequestUrl_InvalidLoginRequest() { var mockRepo = new MockRepository(MockBehavior.Loose); var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); configManager.Setup(w => w.GetIdentityProviderConfigurationAsync(It.IsAny <string>())).Returns(Task.FromResult(_oidcConfig)); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); Assert.That(async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(new IdentityProviderLoginRequest { IdentityProviderId = 0, Tenant = "EDC" }, null), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("requestBaseUrl")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(new IdentityProviderLoginRequest { IdentityProviderId = 0, Tenant = "EDC", RedirectUrl = "" }, null), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("requestBaseUrl")); Assert.That(async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(null, new Uri("http://test.com")), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("idpLoginRequest")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(new IdentityProviderLoginRequest { IdentityProviderId = 100, RedirectUrl = "http://test.com" }, new Uri("http://test.com")), Throws.TypeOf <ArgumentException>().And.Property("ParamName").EqualTo("idpLoginRequest")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(new IdentityProviderLoginRequest { IdentityProviderId = 0, Tenant = "EDC", RedirectUrl = "http://test.com" }, new Uri("http://test.com")), Throws.TypeOf <ArgumentException>().And.Property("ParamName").EqualTo("idpLoginRequest")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl(new IdentityProviderLoginRequest { IdentityProviderId = 0, Tenant = "EDC" }, new Uri("http://test.com")), Throws.TypeOf <ArgumentException>().And.Property("ParamName").EqualTo("idpLoginRequest")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl( new IdentityProviderLoginRequest { IdentityProviderId = 10000, Tenant = "EDC", RedirectUrl = "http://test.com" }, new Uri("http://test.com")), Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The identity provider does not exist.")); Assert.That( async() => await oidcLoginHandler.GetAuthorizationCodeRequestUrl( new IdentityProviderLoginRequest { IdentityProviderId = 10000, Tenant = Guid.NewGuid().ToString(), RedirectUrl = "http://test.com" }, new Uri("http://test.com")), Throws.TypeOf <EntityNotFoundException>()); }
public void GetAuthorizationCodeRequestUrl() { var context = RequestContext.GetContext(); OidcIdentityProvider idProvider; OidcIdentityProviderUser idProviderUser; UserAccount userAccount; // Setup entity model CreateEntityModel("IDP User" + Guid.NewGuid(), false, out idProvider, out idProviderUser, out userAccount); // Create mock var mockRepo = new MockRepository(MockBehavior.Strict); var configUrl = idProvider.OidcIdentityProviderConfigurationUrl; var configManager = mockRepo.Create <IOpenIdConnectConfigurationManager>(); configManager.Setup(w => w.GetIdentityProviderConfigurationAsync(configUrl)).Returns(Task.FromResult(_oidcConfig)); var idpLoginRequest = new IdentityProviderLoginRequest { Tenant = context.Tenant.Name, IdentityProviderId = idProvider.Id, RedirectUrl = "https://test.com/login/callback" }; var baseUri = new Uri("https://test.com"); var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object); var timeStampBefore = DateTime.UtcNow; var uri = Task.Run(() => oidcLoginHandler.GetAuthorizationCodeRequestUrl(idpLoginRequest, baseUri)).Result; var timeStampAfter = DateTime.UtcNow; // Validate url Assert.AreEqual("rndev20adfs.sp.local", uri.Host); Assert.AreEqual("/adfs/oauth2/authorize/", uri.AbsolutePath); var queryValues = uri.ParseQueryString(); Assert.AreEqual(idProvider.OidcClientId, queryValues["client_id"], "The client_id is invalid"); Assert.AreEqual("https://test.com/spapi/data/v1/login/oidc/authresponse/" + context.Tenant.Name.ToLowerInvariant(), queryValues["redirect_uri"], "The redirect_uri is invalid"); Assert.AreEqual("openid email", queryValues["scope"], "The scope is invalid"); Assert.AreEqual("code", queryValues["response_type"], "The response_type is invalid"); Assert.AreEqual("login", queryValues["prompt"], "The prompt is invalid"); var nonce = queryValues["nonce"]; Assert.IsNotNullOrEmpty(nonce, "The nonce is invalid."); var state = queryValues["state"]; Assert.IsNotNullOrEmpty(state, "The state is invalid."); var validatedState = oidcLoginHandler.ValidateAuthState(state); Assert.AreEqual(context.Tenant.Id, validatedState.TenantId, "The state TenantId is invalid"); Assert.AreEqual(idProvider.Id, validatedState.IdentityProviderId, "The state IdentityProviderId is invalid"); Assert.AreEqual(nonce, validatedState.Nonce, "The state Nonce is invalid"); Assert.AreEqual(idpLoginRequest.RedirectUrl, validatedState.RedirectUrl, "The state RedirectUrl is invalid"); var timeStamp = new DateTime(validatedState.Timestamp, DateTimeKind.Utc); // Verify timestamp is between times Assert.GreaterOrEqual(timeStamp, timeStampBefore); Assert.LessOrEqual(timeStamp, timeStampAfter); mockRepo.VerifyAll(); }
// ReSharper disable once InconsistentNaming public async Task <IHttpActionResult> OidcAuthResponseCallback(string tenant, string code = null, string state = null, string error = null, string error_description = null) { OpenIdConnectAuthorizationState authState = null; try { if (!string.IsNullOrWhiteSpace(error)) { return(BadRequest($"An error occurred during authorization. Error:{error}. Description:{error_description}")); } if (string.IsNullOrWhiteSpace(tenant)) { throw new WebArgumentNullException("tenant", "The tenant was not specified"); } if (string.IsNullOrWhiteSpace(code)) { throw new WebArgumentNullException("code", "The code was not specified"); } if (string.IsNullOrWhiteSpace(state)) { throw new WebArgumentNullException("state", "The state was not specified"); } // For some reason ADFS is replacing the + signs (even the encoded ones) with spaces, so we undo it. // State is Base64 encoded so it should not contain spaces. if (!string.IsNullOrWhiteSpace(state)) { state = state.Replace(' ', '+'); } var oidcLoginHandler = new OpenIdConnectLoginHandler(OpenIdConnectConfigurationManager); if (oidcLoginHandler.IsTokenValidationDisabled) { EventLog.Application.WriteError("OpenIdConnectLoginHandler has token validation disabled. This is not be used in production."); throw new AuthenticationException(); } // Validate the state. authState = oidcLoginHandler.ValidateAuthState(state); using (var httpClient = new BasicHttpClient()) { // Process the authorization response. var result = await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenant, code, authState, new Uri(Request.RequestUri.GetLeftPart(UriPartial.Authority)), httpClient); CookieHelper.CreateAuthenticationAndXsrfCookies(authState.TenantId, authState.IdentityProviderId, result.IdentityProviderUserName, result.RequestContextData.Identity.Id, true); } return(Redirect(authState.RedirectUrl)); } catch (Exception exception) { var oidcConfigException = exception as OidcProviderInvalidConfigurationException; EventLog.Application.WriteError("Failed to process oidc authorization response. Error: {0}", exception.ToString()); CookieHelper.DeleteAuthenticationAndXsrfCookies(); if (!string.IsNullOrWhiteSpace(authState?.RedirectUrl)) { string delimiter = authState.RedirectUrl.Contains("?") ? "&" : "?"; string errorType = oidcConfigException != null ? "idpconfigerror" : "autherror"; return(Redirect(authState.RedirectUrl + delimiter + "error=" + errorType)); } return(Unauthorized()); } }