2015-02-13 5 views
7

habe ich ein Projekt mit Spring Security SAML.Spring Security SAML + HTTPS auf eine andere Seite

Ich brauche einen Code (gleiches Projekt) zu schreiben, die mit einem anderen Server durch HTTPS POST mit SOAP verbindet:

PostMethod post = new PostMethod("https://www.somepage.com"); 
    post.setRequestHeader("SOAPAction", "action"); 
    post.setRequestEntity(new StringRequestEntity(soapXML, "text/xml", "UTF-8")); 

    HttpClient httpclient = new HttpClient(); 
    httpclient.executeMethod(post); 

    String responseString = post.getResponseBodyAsString(); 

Es ist ein Fehler:

SSL Peer fehlgeschlagen Host-Name-Validierung für Name: null

Und alle HTTPS-Anfragen werden von Spring Security SAML blockiert.

Konfiguration verwendet für SAML Idp Provider Keys, aber ich brauche Anforderung an einen anderen Server senden:

@Configuration 
@EnableWebMvcSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class, 
org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration.class}) 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl; 

// Initialization of the velocity engine 
@Bean 
public VelocityEngine velocityEngine() { 
    return VelocityFactory.getEngine(); 
} 

// XML parser pool needed for OpenSAML parsing 
@Bean(initMethod = "initialize") 
public StaticBasicParserPool parserPool() { 
    return new StaticBasicParserPool(); 
} 

@Bean(name = "parserPoolHolder") 
public ParserPoolHolder parserPoolHolder() { 
    return new ParserPoolHolder(); 
} 

// Bindings, encoders and decoders used for creating and parsing messages 
@Bean 
public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() { 
    return new MultiThreadedHttpConnectionManager(); 
} 

@Bean 
public HttpClient httpClient() { 
    return new HttpClient(multiThreadedHttpConnectionManager()); 
} 

// SAML Authentication Provider responsible for validating of received SAML 
// messages 
@Bean 
public SAMLAuthenticationProvider samlAuthenticationProvider() { 
    SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider(); 
    samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl); 
    samlAuthenticationProvider.setForcePrincipalAsString(false); 
    return samlAuthenticationProvider; 
} 

// Provider of default SAML Context 
@Bean 
public SAMLContextProviderImpl contextProvider() throws MetadataProviderException { 
    SAMLContextProviderImpl sAMLContextProviderImpl = new SAMLContextProviderImpl(); 
    MetadataCredentialResolver metadataCredentialResolver = new MetadataCredentialResolver(metadata(), keyManager()); 
    metadataCredentialResolver.setUseXmlMetadata(false); 
    sAMLContextProviderImpl.setMetadataResolver(metadataCredentialResolver); 
    return sAMLContextProviderImpl; 
} 

// Initialization of OpenSAML library 
@Bean 
public static SAMLBootstrap sAMLBootstrap() { 
    return new SAMLBootstrap(); 
} 

// Logger for SAML messages and events 
@Bean 
public SAMLDefaultLogger samlLogger() { 
    return new SAMLDefaultLogger(); 
} 

// SAML 2.0 WebSSO Assertion Consumer 
@Bean 
public WebSSOProfileConsumer webSSOprofileConsumer() { 
    return new WebSSOProfileConsumerImpl(); 
} 

// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer 
@Bean 
public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() { 
    return new WebSSOProfileConsumerHoKImpl(); 
} 

// SAML 2.0 Web SSO profile 
@Bean 
public WebSSOProfile webSSOprofile() { 
    return new WebSSOProfileImpl(); 
} 

// SAML 2.0 Holder-of-Key Web SSO profile 
@Bean 
public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() { 
    return new WebSSOProfileConsumerHoKImpl(); 
} 

// SAML 2.0 ECP profile 
@Bean 
public WebSSOProfileECPImpl ecpprofile() { 
    return new WebSSOProfileECPImpl(); 
} 

@Bean 
public SingleLogoutProfile logoutprofile() { 
    return new SingleLogoutProfileImpl(); 
} 

// Central storage of cryptographic keys 
@Bean 
public KeyManager keyManager() { 
    DefaultResourceLoader loader = new DefaultResourceLoader(); 
    Resource storeFile = loader 
    .getResource("classpath:/saml/samlKeystore.jks"); 
    String storePass = "nalle123"; 
    Map<String, String> passwords = new HashMap<String, String>(); 
    passwords.put("apollo", "nalle123"); 
    String defaultKey = "apollo"; 
    return new JKSKeyManager(storeFile, storePass, passwords, defaultKey); 
} 

// Setup TLS Socket Factory 
@Bean 
public TLSProtocolConfigurer tlsProtocolConfigurer() { 
    return new TLSProtocolConfigurer(); 
} 

@Bean 
public ProtocolSocketFactory socketFactory() { 
    return new TLSProtocolSocketFactory(keyManager(), null, "default"); 
} 

@Bean 
public Protocol socketFactoryProtocol() { 
    return new Protocol("https", socketFactory(), 443); 
} 

@Bean 
public MethodInvokingFactoryBean socketFactoryInitialization() { 
    MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean(); 
    methodInvokingFactoryBean.setTargetClass(Protocol.class); 
    methodInvokingFactoryBean.setTargetMethod("registerProtocol"); 
    Object[] args = {"https", socketFactoryProtocol()}; 
    methodInvokingFactoryBean.setArguments(args); 
    return methodInvokingFactoryBean; 
} 

@Bean 
public WebSSOProfileOptions defaultWebSSOProfileOptions() { 
    WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions(); 
    webSSOProfileOptions.setIncludeScoping(false); 
    return webSSOProfileOptions; 
} 

// Entry point to initialize authentication, default values taken from 
// properties file 
@Bean 
public SAMLEntryPoint samlEntryPoint() { 
    SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint(); 
    samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions()); 
    return samlEntryPoint; 
} 

// Setup advanced info about metadata 
@Bean 
public ExtendedMetadata extendedMetadata() { 
    ExtendedMetadata extendedMetadata = new ExtendedMetadata(); 
    extendedMetadata.setIdpDiscoveryEnabled(false); 
    extendedMetadata.setSignMetadata(true); 
    return extendedMetadata; 
} 

// IDP Discovery Service 
@Bean 
public SAMLDiscovery samlIDPDiscovery() { 
    SAMLDiscovery idpDiscovery = new SAMLDiscovery(); 
    idpDiscovery.setIdpSelectionPath("/saml/idpSelection"); 
    return idpDiscovery; 
} 

@Bean 
@Qualifier("idp-ssocircle") 
public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider() 
     throws MetadataProviderException { 
    @SuppressWarnings({"deprecation"}) 
    //HTTPMetadataProvider httpMetadataProvider 
    // = new HTTPMetadataProvider("https://idp.ssocircle.com/idp-meta.xml", 5000); 

    FilesystemMetadataProvider httpMetadataProvider = new FilesystemMetadataProvider(new File("FederationMetadata.xml")); 
    httpMetadataProvider.setParserPool(parserPool() 
    ); 
    ExtendedMetadataDelegate extendedMetadataDelegate 
      = new ExtendedMetadataDelegate(httpMetadataProvider, extendedMetadata()); 
    extendedMetadataDelegate.setMetadataTrustCheck(false); 
    extendedMetadataDelegate.setMetadataRequireSignature(false); 
    return extendedMetadataDelegate; 
} 

// IDP Metadata configuration - paths to metadata of IDPs in circle of trust 
// is here 
// Do no forget to call iniitalize method on providers 
@Bean 
@Qualifier("metadata") 
public CachingMetadataManager metadata() throws MetadataProviderException { 
    List<MetadataProvider> providers = new ArrayList<MetadataProvider>(); 
    providers.add(ssoCircleExtendedMetadataProvider()); 
    return new CachingMetadataManager(providers); 
} 

// Filter automatically generates default SP metadata 
@Bean 
public MetadataGenerator metadataGenerator() { 
    MetadataGenerator metadataGenerator = new MetadataGenerator(); 
    metadataGenerator.setEntityId("com:vdenotaris:spring:sp"); 
    metadataGenerator.setExtendedMetadata(extendedMetadata()); 
    metadataGenerator.setIncludeDiscoveryExtension(false); 
    metadataGenerator.setKeyManager(keyManager()); 
    return metadataGenerator; 
} 

// The filter is waiting for connections on URL suffixed with filterSuffix 
// and presents SP metadata there 
@Bean 
public MetadataDisplayFilter metadataDisplayFilter() { 
    return new MetadataDisplayFilter(); 
} 

// Handler deciding where to redirect user after successful login 
@Bean 
public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() { 
    SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler 
      = new SavedRequestAwareAuthenticationSuccessHandler(); 
    successRedirectHandler.setDefaultTargetUrl("/landing"); 
    return successRedirectHandler; 
} 

// Handler deciding where to redirect user after failed login 
@Bean 
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() { 
    SimpleUrlAuthenticationFailureHandler failureHandler 
      = new SimpleUrlAuthenticationFailureHandler(); 
    failureHandler.setUseForward(true); 
    failureHandler.setDefaultFailureUrl("/error"); 
    return failureHandler; 
} 

@Bean 
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception { 
    SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter = new SAMLWebSSOHoKProcessingFilter(); 
    samlWebSSOHoKProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler()); 
    samlWebSSOHoKProcessingFilter.setAuthenticationManager(authenticationManager()); 
    samlWebSSOHoKProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler()); 
    return samlWebSSOHoKProcessingFilter; 
} 

// Processing filter for WebSSO profile messages 
@Bean 
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception { 
    SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter(); 
    samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager()); 
    samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler()); 
    samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler()); 
    return samlWebSSOProcessingFilter; 
} 

@Bean 
public MetadataGeneratorFilter metadataGeneratorFilter() { 
    return new MetadataGeneratorFilter(metadataGenerator()); 
} 

// Handler for successful logout 
@Bean 
public SimpleUrlLogoutSuccessHandler successLogoutHandler() { 
    SimpleUrlLogoutSuccessHandler successLogoutHandler = new SimpleUrlLogoutSuccessHandler(); 
    successLogoutHandler.setDefaultTargetUrl("/"); 
    return successLogoutHandler; 
} 

// Logout handler terminating local session 
@Bean 
public SecurityContextLogoutHandler logoutHandler() { 
    SecurityContextLogoutHandler logoutHandler 
      = new SecurityContextLogoutHandler(); 
    logoutHandler.setInvalidateHttpSession(true); 
    logoutHandler.setClearAuthentication(true); 
    return logoutHandler; 
} 

// Filter processing incoming logout messages 
// First argument determines URL user will be redirected to after successful 
// global logout 
@Bean 
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() { 
    return new SAMLLogoutProcessingFilter(successLogoutHandler(), 
      logoutHandler()); 
} 

// Overrides default logout processing filter with the one processing SAML 
// messages 
@Bean 
public SAMLLogoutFilter samlLogoutFilter() { 
    return new SAMLLogoutFilter(successLogoutHandler(), 
      new LogoutHandler[]{logoutHandler()}, 
      new LogoutHandler[]{logoutHandler()}); 
} 

// Bindings 
private ArtifactResolutionProfile artifactResolutionProfile() { 
    final ArtifactResolutionProfileImpl artifactResolutionProfile 
      = new ArtifactResolutionProfileImpl(httpClient()); 
    artifactResolutionProfile.setProcessor(new SAMLProcessorImpl(soapBinding())); 
    return artifactResolutionProfile; 
} 

@Bean 
public HTTPArtifactBinding artifactBinding(ParserPool parserPool, VelocityEngine velocityEngine) { 
    return new HTTPArtifactBinding(parserPool, velocityEngine, artifactResolutionProfile()); 
} 

@Bean 
public HTTPSOAP11Binding soapBinding() { 
    return new HTTPSOAP11Binding(parserPool()); 
} 

@Bean 
public HTTPPostBinding httpPostBinding() { 
    return new HTTPPostBinding(parserPool(), velocityEngine()); 
} 

@Bean 
public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() { 
    return new HTTPRedirectDeflateBinding(parserPool()); 
} 

@Bean 
public HTTPSOAP11Binding httpSOAP11Binding() { 
    return new HTTPSOAP11Binding(parserPool()); 
} 

@Bean 
public HTTPPAOS11Binding httpPAOS11Binding() { 
    return new HTTPPAOS11Binding(parserPool()); 
} 

// Processor 
@Bean 
public SAMLProcessorImpl processor() { 
    Collection<SAMLBinding> bindings = new ArrayList<SAMLBinding>(); 
    bindings.add(httpRedirectDeflateBinding()); 
    bindings.add(httpPostBinding()); 
    bindings.add(artifactBinding(parserPool(), velocityEngine())); 
    bindings.add(httpSOAP11Binding()); 
    bindings.add(httpPAOS11Binding()); 
    return new SAMLProcessorImpl(bindings); 
} 

/** 
* Define the security filter chain in order to support SSO Auth by using 
* SAML 2.0 
* 
* @return Filter chain proxy 
* @throws Exception 
*/ 
@Bean 
public FilterChainProxy samlFilter() throws Exception { 
    List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>(); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"), 
      samlEntryPoint())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"), 
      samlLogoutFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"), 
      metadataDisplayFilter())); 
    //chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"), 
    //  samlWebSSOProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSOHoK/**"), 
      samlWebSSOHoKProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"), 
      samlLogoutProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"), 
      samlIDPDiscovery())); 
    return new FilterChainProxy(chains); 
} 

/** 
* Returns the authentication manager currently used by Spring. It 
* represents a bean definition with the aim allow wiring from other classes 
* performing the Inversion of Control (IoC). 
* 
* @throws Exception 
*/ 
@Bean 
@Override 
public AuthenticationManager authenticationManagerBean() throws Exception { 
    return super.authenticationManagerBean(); 
} 

/** 
* Defines the web based security configuration. 
* 
* @param http It allows configuring web based security for specific http 
* requests. 
* @throws Exception 
*/ 
@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .httpBasic() 
      .authenticationEntryPoint(samlEntryPoint()); 
    http 
      .csrf() 
      .disable(); 
    http 
      .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class) 
      .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class); 
    http 
      .authorizeRequests() 
      .antMatchers("/").permitAll() 
      .antMatchers("/index.html").permitAll() 
      .antMatchers("/index").permitAll() 
      .antMatchers("/error").permitAll() 
      .antMatchers("/login").permitAll() 
      .antMatchers("/saml/**").permitAll() 
      .anyRequest().authenticated() 
      .and().formLogin().loginPage("/login").permitAll(); 

    http 
      .logout() 
      .logoutSuccessUrl("/"); 
} 

/** 
* Sets a custom authentication provider. 
* 
* @param auth SecurityBuilder used to create an AuthenticationManager. 
* @throws Exception 
*/ 
@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth 
      .authenticationProvider(samlAuthenticationProvider()); 
} 

} 

Logs:

[ERROR] org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=test.test.pl,OU=test,O=test,L=test,ST=test,C=PL,2.5.4.5=#1320487a772f77645a513079554c4c346c3246716c76616f64694f6f34643149676a']: unable to find valid certification path to requested target 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Trust of untrusted credential could not be established via PKIX validation 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Attempting PKIX validation of untrusted credential 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Beginning PKIX validation using trusted validation information 
[DEBUG] org.opensaml.xml.security.x509.BasicX509CredentialNameEvaluator - Supplied trusted names are null or empty, skipping name evaluation 
[ERROR] org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=test.test.pl,OU=test,O=test,L=test,ST=test,C=PL,2.5.4.5=#1320487a772f77645a513079554c4c346c3246716c76616f64694f6f34643149676a']: unable to find valid certification path to requested target 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Trust of untrusted credential could not be established via PKIX validation 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Attempting PKIX validation of untrusted credential 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Beginning PKIX validation using trusted validation information 
[DEBUG] org.opensaml.xml.security.x509.BasicX509CredentialNameEvaluator - Supplied trusted names are null or empty, skipping name evaluation 
[ERROR] org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=test.test.pl,OU=test,O=test,L=test,ST=test,C=PL,2.5.4.5=#1320487a772f77645a513079554c4c346c3246716c76616f64694f6f34643149676a']: unable to find valid certification path to requested target 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Trust of untrusted credential could not be established via PKIX validation 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Attempting PKIX validation of untrusted credential 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Beginning PKIX validation using trusted validation information 
[DEBUG] org.opensaml.xml.security.x509.BasicX509CredentialNameEvaluator - Supplied trusted names are null or empty, skipping name evaluation 
[ERROR] org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='test,O=test,L=test,ST=test,C=PL,2.5.4.5=#1320487a772f77645a513079554c4c346c3246716c76616f64694f6f34643149676a']: unable to find valid certification path to requested target 
[DEBUG] org.opensaml.xml.security.x509.PKIXX509CredentialTrustEngine - Trust of untrusted credential could not be established via PKIX validation 
+0

Verwenden Sie bean "org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer"? –

+0

Bitte fügen Sie Ihre Federkonfiguration und vollständige Protokolle. –

Antwort

7

Sie verwenden Bean TLSProtocolConfigurer die vertrauenswürdige Zertifikate und Hostname ändert Überprüfung des HTTPS-Protokolls im HTTP-Client. Sie können durch das Entfernen dieses Bean Verhalten des HTTP-Client wieder auf die Standardwerte zurückgesetzt. Sie werden dann sicherstellen müssen, dass von Unternehmen verwendet, Zertifikate, von denen Sie Metadaten laden (https://idp.ssocircle.com/idp-meta.xml) in Ihrem cacerts vertrauenswürdig sind, oder einen Endpunkt verwenden, ohne https (http://idp.ssocircle.com/idp-meta.xml).

Alternativ können Sie den Hostnamen Überprüfung deaktivieren, indem TLSProtocolConfigurer Eigenschaft sslHostnameVerification-allowAll auf Bohnen Einstellung. Sie werden auch sicherstellen müssen, dass das HTTPS-Zertifikat von https://www.somepage.com (oder dessen CA) in den samlKeystore.jks enthalten ist (siehe Spring SAML manual).

Sie können weitere Einzelheiten über die TLSProtocolConfigurer Bohne in der Spring SAML manual, chapter HTTP-based metadata provider with SSL finden.

Verwandte Themen