import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
import org.sonar.api.server.authentication.UserIdentity;
import org.sonar.api.server.http.HttpRequest;
import org.sonar.api.server.http.HttpResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.server.http.JavaxHttpRequest;
import org.sonar.server.http.JavaxHttpResponse;
HttpServletResponse httpServletResponse = ((JavaxHttpResponse) response).getDelegate();
return new Auth(initSettings(callbackUrl), httpServletRequest, httpServletResponse);
- } catch (SettingsException e) {
+ } catch (Exception e) {
throw new IllegalStateException("Failed to create a SAML Auth", e);
}
}
var saml2Settings = new SettingsBuilder().fromValues(samlData).build();
if (samlSettings.getServiceProviderPrivateKey().isPresent() && saml2Settings.getSPkey() == null) {
- LOGGER.error("Error in parsing service provider private key, please make sure that it is in PKCS 8 format.");
+ final String pkcs8ErrorMessage = "Error in parsing service provider private key, please make sure that it is in PKCS 8 format.";
+ LOGGER.error(pkcs8ErrorMessage);
+ // If signature is enabled then we need to throw an exception because the authentication will never work with a missing private key
+ if (samlSettings.isSignRequestsEnabled()) {
+ throw new IllegalStateException(pkcs8ErrorMessage);
+ }
}
return saml2Settings;
}
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.http.HttpRequest;
import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.utils.System2;
import org.sonar.server.http.JavaxHttpRequest;
import org.sonar.server.http.JavaxHttpResponse;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SamlAuthenticatorTest {
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, SamlSettings.definitions()));
+
+ private SamlSettings samlSettings = new SamlSettings(settings.asConfig());
+
+ private final SamlAuthenticator underTest = new SamlAuthenticator(samlSettings, mock(SamlMessageIdChecker.class));
+
@Test
public void authentication_status_with_errors_returned_when_init_fails() {
- SamlAuthenticator samlAuthenticator = new SamlAuthenticator(mock(SamlSettings.class), mock(SamlMessageIdChecker.class));
HttpRequest request = new JavaxHttpRequest(mock(HttpServletRequest.class));
HttpResponse response = new JavaxHttpResponse(mock(HttpServletResponse.class));
when(request.getContextPath()).thenReturn("context");
- String authenticationStatus = samlAuthenticator.getAuthenticationStatusPage(request, response);
+ String authenticationStatus = underTest.getAuthenticationStatusPage(request, response);
assertFalse(authenticationStatus.isEmpty());
}
+
+ @Test
+ public void givenPrivateKeyIsNotPkcs8Encrypted_whenInitializingTheAuthentication_thenExceptionIsThrown() {
+ initBasicSamlSettings();
+
+ settings.setProperty("sonar.auth.saml.signature.enabled", true);
+ settings.setProperty("sonar.auth.saml.sp.certificate.secured", "CERTIFICATE");
+ settings.setProperty("sonar.auth.saml.sp.privateKey.secured", "Not a PKCS8 key");
+
+ assertThatIllegalStateException()
+ .isThrownBy(() -> underTest.initLogin("","", mock(JavaxHttpRequest.class), mock(JavaxHttpResponse.class)))
+ .withMessage("Failed to create a SAML Auth")
+ .havingCause()
+ .withMessage("Error in parsing service provider private key, please make sure that it is in PKCS 8 format.");
+ }
+
+ @Test
+ public void givenMissingSpCertificate_whenInitializingTheAuthentication_thenExceptionIsThrown() {
+ initBasicSamlSettings();
+
+ settings.setProperty("sonar.auth.saml.signature.enabled", true);
+ settings.setProperty("sonar.auth.saml.sp.privateKey.secured", "PRIVATE_KEY");
+
+ assertThatIllegalStateException()
+ .isThrownBy(() -> underTest.initLogin("","", mock(JavaxHttpRequest.class), mock(JavaxHttpResponse.class)))
+ .withMessage("Failed to create a SAML Auth")
+ .havingCause()
+ .withMessage("Service provider certificate is missing");
+ }
+
+ private void initBasicSamlSettings() {
+ settings.setProperty("sonar.auth.saml.applicationId", "MyApp");
+ settings.setProperty("sonar.auth.saml.providerId", "http://localhost:8080/auth/realms/sonarqube");
+ settings.setProperty("sonar.auth.saml.loginUrl", "http://localhost:8080/auth/realms/sonarqube/protocol/saml");
+ settings.setProperty("sonar.auth.saml.certificate.secured", "ABCDEFG");
+ settings.setProperty("sonar.auth.saml.user.login", "login");
+ settings.setProperty("sonar.auth.saml.user.name", "name");
+ settings.setProperty("sonar.auth.saml.enabled", true);
+ }
+
}