@Test public void getWhenUsingX509AndPropertyPlaceholderThenSubjectPrincipalRegexIsConfigured() throws Exception { System.setProperty("subject_principal_regex", "OU=(.*?)(?:,|$)"); this.spring.configLocations(xml("X509")).autowire(); this.mvc.perform(get("/protected") .with(x509("classpath:org/springframework/security/config/http/MiscHttpConfigTests-certificate.pem"))) .andExpect(status().isOk()); }
@Test public void loginWhenUsingCustomAuthenticationDetailsSourceRefThenAuthenticationSourcesDetailsAccordingly() throws Exception { this.spring.configLocations(xml("CustomAuthenticationDetailsSourceRef")).autowire(); Object details = mock(Object.class); AuthenticationDetailsSource source = this.spring.getContext().getBean(AuthenticationDetailsSource.class); when(source.buildDetails(any(Object.class))).thenReturn(details); this.mvc.perform(get("/details") .with(httpBasic("user", "password"))) .andExpect(content().string(details.getClass().getName())); this.mvc.perform(get("/details") .with(x509("classpath:org/springframework/security/config/http/MiscHttpConfigTests-certificate.pem"))) .andExpect(content().string(details.getClass().getName())); MockHttpSession session = (MockHttpSession) this.mvc.perform(post("/login") .param("username", "user") .param("password", "password") .with(csrf())) .andReturn().getRequest().getSession(false); this.mvc.perform(get("/details") .session(session)) .andExpect(content().string(details.getClass().getName())); assertThat(getField(getFilter(OpenIDAuthenticationFilter.class), "authenticationDetailsSource")) .isEqualTo(source); }
/** * Finds an X509Cetificate using a resoureName and populates it on the request. * * @param resourceName the name of the X509Certificate resource * @return the * {@link org.springframework.test.web.servlet.request.RequestPostProcessor} to use. * @throws IOException * @throws CertificateException */ public static RequestPostProcessor x509(String resourceName) throws IOException, CertificateException { ResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource(resourceName); InputStream inputStream = resource.getInputStream(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) certFactory .generateCertificate(inputStream); return x509(certificate); }
/** * Finds an X509Cetificate using a resoureName and populates it on the request. * * @param resourceName the name of the X509Certificate resource * @return the * {@link org.springframework.test.web.servlet.request.RequestPostProcessor} to use. * @throws IOException * @throws CertificateException */ public static RequestPostProcessor x509(String resourceName) throws IOException, CertificateException { ResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource(resourceName); InputStream inputStream = resource.getInputStream(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) certFactory .generateCertificate(inputStream); return x509(certificate); }
@Test public void GET_byVersions_whenTheUserDoesntHavePermissionToReadCredential_returns404() throws Exception { final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.SELF_SIGNED_CERT_WITH_CLIENT_AUTH_EXT); final MockHttpServletRequestBuilder get = get("/api/v1/data?name=" + CREDENTIAL_NAME + "&versions=2") .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())); final String expectedError = "The request could not be completed because the credential does not exist or you do not have sufficient authorization."; mockMvc.perform(get) .andDo(print()) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.error", equalTo(expectedError))); }
@Test public void GET_byCredentialName_whenTheUserDoesntHavePermissionToReadCredential_returns404() throws Exception { final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.SELF_SIGNED_CERT_WITH_CLIENT_AUTH_EXT); final MockHttpServletRequestBuilder get = get("/api/v1/data?name=" + CREDENTIAL_NAME) .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())); final String expectedError = "The request could not be completed because the credential does not exist or you do not have sufficient authorization."; mockMvc.perform(get) .andDo(print()) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.error", equalTo(expectedError))); }
@Test public void GET_byId_whenTheUserDoesntHavePermissionToReadCredential_returns404() throws Exception { final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.SELF_SIGNED_CERT_WITH_CLIENT_AUTH_EXT); final MockHttpServletRequestBuilder get = get("/api/v1/data/" + uuid) .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())); final String expectedError = "The request could not be completed because the credential does not exist or you do not have sufficient authorization."; mockMvc.perform(get) .andDo(print()) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.error", equalTo(expectedError))); }
@Test public void dataEndpoint_withMutualTLS_deniesClientCertsWithoutOrgUnit() throws Exception { setupDataEndpointMocks(); final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.TEST_CERT_WITHOUT_ORGANIZATION_UNIT); final MockHttpServletRequestBuilder post = post(dataApiPath) .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) .content("{\"type\":\"password\",\"name\":\"" + credentialName + "\"}"); final String expectedError = "The provided authentication mechanism does not provide a " + "valid identity. Please contact your system administrator."; mockMvc.perform(post) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.error").value(expectedError)); }
@Test public void dataEndpoint_withMutualTLS_deniesClientCertsWithOrgUnitsThatDontContainV4UUID() throws Exception { setupDataEndpointMocks(); final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.TEST_CERT_WITH_INVALID_UUID_IN_ORGANIZATION_UNIT); final MockHttpServletRequestBuilder post = post(dataApiPath) .with(SecurityMockMvcRequestPostProcessors.x509( certificateReader.getCertificate())) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) .content("{\"type\":\"password\",\"name\":\"" + credentialName + "\"}"); final String expectedError = "The provided authentication mechanism does not " + "provide a valid identity. Please contact your system administrator."; mockMvc.perform(post) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.error").value(expectedError)); }
@Test public void dataEndpoint_withMutualTLS_deniesClientCertsWithOrgUnitNotPrefixedAccurately() throws Exception { setupDataEndpointMocks(); final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.TEST_CERT_WITH_INVALID_ORGANIZATION_UNIT_PREFIX); final MockHttpServletRequestBuilder post = post(dataApiPath) .with(SecurityMockMvcRequestPostProcessors.x509( certificateReader.getCertificate())) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) .content("{\"type\":\"password\",\"name\":\"" + credentialName + "\"}"); final String expectedError = "The provided authentication mechanism does not provide a " + "valid identity. Please contact your system administrator."; mockMvc.perform(post) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.error").value(expectedError)); }
@Test public void dataEndpoint_withMutualTLS_deniesClientCertsWithoutClientAuthExtension() throws Exception { setupDataEndpointMocks(); final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.SELF_SIGNED_CERT_WITH_NO_CLIENT_AUTH_EXT); final MockHttpServletRequestBuilder post = post(dataApiPath) .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) .content("{\"type\":\"password\",\"name\":\"" + credentialName + "\"}"); mockMvc.perform(post) .andDo(print()) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.error") .value( "The provided certificate is not authorized to be used for client authentication.")); }
@Test public void dataEndpoint_withMutualTLS_allowsAllClientCertsWithValidOrgUnitAndClientAuthExtensions() throws Exception { setupDataEndpointMocks(); final CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.SELF_SIGNED_CERT_WITH_CLIENT_AUTH_EXT); final MockHttpServletRequestBuilder post = post(dataApiPath) .with(SecurityMockMvcRequestPostProcessors .x509(certificateReader.getCertificate())) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) .content("{\"type\":\"password\",\"name\":\"" + credentialName + "\"}"); mockMvc.perform(post) .andExpect(status().isOk()) .andExpect(jsonPath("$.type").value("password")) .andExpect(jsonPath("$.version_created_at").exists()) .andExpect(jsonPath("$.value").exists()); }