2016-07-29 18 views
1

openAmを使用してユーザーを認証し、ユーザーを再度認証せずにセッションを共有して他のマイクロサービスと通信したいと考えています。セッションの詳細は外部データベースに保存されます。私はこれを達成するためにすべてのJava設定で春のセキュリティsamlサンプルアプリケーションを使用しています。 2つのセッションが生成されています。 1つはIDPにログする前、もう1つは資格情報を入力した後です。私がopenAmでチェックすると、ユーザーはログインしているが、アプリケーションでは、応答メッセージのInResponseToFieldを指定してSAMLExceptionを取得すると、送信メッセージ12345(ランダムID)に対応する。 springセッションとsamlを統合するにはどうすればよいですか? SessionRepositoryを実装春のセキュリティsamlとのSpringの統合

私のサンプルアプリケーションのセキュリティ設定ファイル

package com.vdenotaris.spring.boot.security.saml.web.config; 
@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl; 


    @Bean 
    public VelocityEngine velocityEngine() { 
     return VelocityFactory.getEngine(); 
    } 


    @Bean(initMethod = "initialize") 
    public StaticBasicParserPool parserPool() { 
     return new StaticBasicParserPool(); 
    } 

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


    @Bean 
    public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() { 
     return new MultiThreadedHttpConnectionManager(); 
    } 

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

    @Bean 
    public SAMLAuthenticationProvider samlAuthenticationProvider() { 
     SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider(); 
     samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl); 
     samlAuthenticationProvider.setForcePrincipalAsString(false); 
     return samlAuthenticationProvider; 
    }  
    @Bean 
    public SAMLContextProviderImpl contextProvider() { 
     return new SAMLContextProviderImpl(); 
    }  

    @Bean 
    public static SAMLBootstrap sAMLBootstrap() { 
     return new SAMLBootstrap(); 
    }  

    @Bean 
    public SAMLDefaultLogger samlLogger() { 
     return new SAMLDefaultLogger(); 
    } 
    @Bean 
    public WebSSOProfileConsumer webSSOprofileConsumer() { 
     return new WebSSOProfileConsumerImpl(); 
    } 
    @Bean 
    public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() { 
     return new WebSSOProfileConsumerHoKImpl(); 
    } 
    @Bean 
    public WebSSOProfile webSSOprofile() { 
     return new WebSSOProfileImpl(); 
    } 
    @Bean 
    public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() { 
     return new WebSSOProfileConsumerHoKImpl(); 
    } 
    @Bean 
    public WebSSOProfileECPImpl ecpprofile() { 
     return new WebSSOProfileECPImpl(); 
    } 

    @Bean 
    public SingleLogoutProfile logoutprofile() { 
     return new SingleLogoutProfileImpl(); 
    } 
    @Bean 
    public KeyManager keyManager() { 
     DefaultResourceLoader loader = new DefaultResourceLoader(); 
     Resource storeFile = loader 
       .getResource("classpath:/saml/keystore.jks"); 
     String storePass = "password"; 
     Map<String, String> passwords = new HashMap<String, String>(); 
     passwords.put("mydomain", "password"); 
     String defaultKey = "mydomain"; 
     return new JKSKeyManager(storeFile, storePass, passwords, defaultKey); 
    } 
    @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; 
    } 
    @Bean 
    public ExtendedMetadata extendedMetadata() { 
     ExtendedMetadata extendedMetadata = new ExtendedMetadata(); 
     extendedMetadata.setIdpDiscoveryEnabled(true); 
     extendedMetadata.setSignMetadata(false); 
     return extendedMetadata; 
    } 

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

    @Bean 
    @Qualifier("idp-ssocircle") 
    public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider() 
     throws MetadataProviderException { 
    String idpSSOCircleMetadataURL = "http://openam.com:8080/OpenAM/saml2/jsp/exportmetadata.jsp"; 
    Timer backgroundTaskTimer = new Timer(true); 
    HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(
     backgroundTaskTimer, httpClient(), idpSSOCircleMetadataURL); 
    httpMetadataProvider.setParserPool(parserPool()); 
    ExtendedMetadataDelegate extendedMetadataDelegate = 
     new ExtendedMetadataDelegate(httpMetadataProvider, extendedMetadata()); 
    extendedMetadataDelegate.setMetadataTrustCheck(true); 
    extendedMetadataDelegate.setMetadataRequireSignature(false); 
    return extendedMetadataDelegate; 
    } 
    @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("http://localhost:8080/spring-boot-security-saml2-sample/saml/web/metadata"); 
     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("/");  
     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; 
    } 
    @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()); 
    } 
    @Bean 
    public SimpleUrlLogoutSuccessHandler successLogoutHandler() { 
     SimpleUrlLogoutSuccessHandler successLogoutHandler = new SimpleUrlLogoutSuccessHandler(); 
     successLogoutHandler.setDefaultTargetUrl("/"); 
     return successLogoutHandler; 
    } 
    @Bean 
    public SecurityContextLogoutHandler logoutHandler() { 
     SecurityContextLogoutHandler logoutHandler = 
      new SecurityContextLogoutHandler(); 
     logoutHandler.setInvalidateHttpSession(true); 
     logoutHandler.setClearAuthentication(true); 
     return logoutHandler; 
    } 

    @Bean 
    public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() { 
     return new SAMLLogoutProcessingFilter(successLogoutHandler(), 
       logoutHandler()); 
    }   
    @Bean 
    public SAMLLogoutFilter samlLogoutFilter() { 
     return new SAMLLogoutFilter(successLogoutHandler(), 
       new LogoutHandler[] { logoutHandler() }, 
       new LogoutHandler[] { logoutHandler() }); 
    } 

    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); 
    } 
    @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); 
    } 
    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 


    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .httpBasic() 
       .authenticationEntryPoint(samlEntryPoint()); 
     http 
      .csrf() 
      .disable(); 
     http 
      .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class) 
      .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class) 
      .addFilterBefore(sessionRepositoryFilter(sessionRepository(), httpSessionStrategy()), 
       ChannelProcessingFilter.class) 
       .sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED); 
     http   
      .authorizeRequests() 
      .antMatchers("/").permitAll() 
      .antMatchers("/publicUrl").permitAll() 
      .antMatchers("/app/**").permitAll() 
      .antMatchers("/error").permitAll() 
      .antMatchers("/saml/**").permitAll() 
      .antMatchers("/landing").authenticated(); 

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

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
      .authenticationProvider(samlAuthenticationProvider()); 
    } 

    @Bean 
    public HttpSessionStrategy httpSessionStrategy() 
    { 
     return new HeaderHttpSessionStrategy(); 
    }  

    @Bean 
    public SessionRepositoryFilter<ExpiringSession> sessionRepositoryFilter(
        SessionRepository<ExpiringSession> sessionRepository, HttpSessionStrategy httpSessionStrategy) 
    { 
     SessionRepositoryFilter<ExpiringSession> sessionRepositoryFilter = new SessionRepositoryFilter<>(
         sessionRepository); 
     sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy); 
     return sessionRepositoryFilter; 
    } 

    @Bean 
    public SessionRepository<ExpiringSession> sessionRepository() 
    { 
     return new JPASessionRepository(1800); 
    }  
} 

JPAセッションリポジトリは次のとおりです。

package com.security.repositories.session; 
    public class JPASessionRepository implements SessionRepository<ExpiringSession> 
    { 

     private static final Logger LOG = LogManager.getLogger(JPASessionRepository.class); 

     private int maxInactiveInterval = -1; 

     @Autowired 
     private SpringSessionRepository springSessionRepository; 

     public JPASessionRepository() 
     {    
     } 
     public JPASessionRepository(int maxInactiveInterval) 
     { 
      this.maxInactiveInterval = maxInactiveInterval; 
     }  
     @Override 
     public ExpiringSession createSession() 
     { 
      ExpiringSession result = new MapSession(); 
      result.setMaxInactiveIntervalInSeconds(maxInactiveInterval); 
      return result; 
     } 

     @Transactional 
     @Override 
     public void save(ExpiringSession session) 
     { 
      springSessionRepository.save(convertToDomain(session)); 
     } 

     @Transactional 
     @Override 
     public ExpiringSession getSession(String id) 
     { 
      SessionEntity sessionEntity = springSessionRepository.findOne(id); 
      ExpiringSession saved = null; 
      if(sessionEntity != null) 
      { 
       saved = convertToSession(sessionEntity); 
      } 

      if (saved == null) 
      { 
       return null; 
      } 
      if (saved.isExpired()) 
      { 
       delete(saved.getId()); 
       return null; 
      } 
      return saved; 
     } 
     @Override 
     public void delete(String id) 
     { 
      SessionEntity currentSession = springSessionRepository.findOne(id); 
      if (null != currentSession) 
      { 
       springSessionRepository.delete(id); 
      } 
     } 
     private SessionEntity convertToDomain(ExpiringSession session) 
     { 
      SessionEntity sessionEntity = new SessionEntity(); 
      sessionEntity.setId(session.getId()); 
      sessionEntity.setLastAccessedTime(session.getLastAccessedTime()); 
      sessionEntity.setCreationTime(session.getCreationTime()); 
      sessionEntity.setData(serializeAttributes(session)); 
      return sessionEntity; 
     } 
     byte[] serializeAttributes(ExpiringSession session) 
     { 
      Map<String, Object> attributes = new HashMap<>(); 
      for (String attrName : session.getAttributeNames()) 
      { 
       attributes.put(attrName, session.getAttribute(attrName)); 

      } 
      ByteArrayOutputStream out = new ByteArrayOutputStream(); 
      byte[] buffer; 
      try 
      { 
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(out); 
       objectOutputStream.writeObject(new SessionAttributes(attributes)); 
       buffer = out.toByteArray(); 
       objectOutputStream.close(); 
      } 
      catch (IOException e) 
      { 
       throw new RuntimeException(e); 
      } 

      return buffer; 
     }  

     private ExpiringSession convertToSession(SessionEntity sessionEntity) 
     { 
      MapSession mapSession = new MapSession(); 
      mapSession.setId(sessionEntity.getId()); 
      mapSession.setLastAccessedTime(sessionEntity.getLastAccessedTime()); 
      mapSession.setCreationTime(sessionEntity.getCreationTime()); 
      mapSession.setMaxInactiveIntervalInSeconds(this.maxInactiveInterval); 

      SessionAttributes attributes = deserializeAttributes(sessionEntity); 
      if (attributes != null) 
      { 
       for (Map.Entry<String, Object> attribute : attributes.getAttributes().entrySet()) 
       { 
        mapSession.setAttribute(attribute.getKey(), attribute.getValue()); 
       } 
      } 
      return mapSession; 
     }  
     private SessionAttributes deserializeAttributes(SessionEntity sessionEntity) 
     { 
      SessionAttributes attributes = null; 
      if (sessionEntity.getData() != null && sessionEntity.getData().length > 0) 
      { 
       try 
       { 
        ObjectInputStream objectInputStream = new ObjectInputStream(
            new ByteArrayInputStream(sessionEntity.getData())); 

        Object obj = objectInputStream.readObject();      

        attributes = (SessionAttributes) obj; 
        objectInputStream.close(); 
       } 
       catch (IOException | ClassNotFoundException e) 
       { 
        LOG.warn(e); 
        //FIXME:How should this exception be handled? 
       } 
      } 
      return attributes; 
     }  

     public Integer getDefaultMaxInactiveInterval() 
     { 
      return maxInactiveInterval; 
     }  
     public void setDefaultMaxInactiveInterval(int maxInactiveInterval) 
     { 
      this.maxInactiveInterval = maxInactiveInterval; 
     }  

     public SpringSessionRepository getSpringSessionRepository() 
     { 
      return springSessionRepository; 
     }  
     public void setSpringSessionRepository(SpringSessionRepository springSessionRepository) 
     { 
      this.springSessionRepository = springSessionRepository; 
     } 
    } 

SPメタデータ

<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="http___localhost_8080_spring-boot-security-saml2-sample_saml_web_metadata" entityID="http://localhost:8080/spring-boot-security-saml2-sample/saml/web/metadata"><md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>x509 certificate data</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:KeyDescriptor use="encryption"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>--x509 certificate</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/saml/SingleLogout"/><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/saml/SingleLogout"/><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</md:NameIDFormat><md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/saml/SSO" index="0" isDefault="true"/><md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8080/saml/SSO" index="1"/></md:SPSSODescriptor></md:EntityDescriptor> 

IDPのメタデータ: -

<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://localhost:8081/OpenAM"> 
    <IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> 
    <KeyDescriptor use="signing"> 
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:X509Data> 
    <ds:X509Certificate> 
    sample certificate 
    </ds:X509Certificate> 
    </ds:X509Data> 
    </ds:KeyInfo> 
    </KeyDescriptor> 
    <ArtifactResolutionService index="0" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/ArtifactResolver/metaAlias/idp"/> 
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8081/OpenAM/IDPSloRedirect/metaAlias/idp" ResponseLocation="http://localhost:8081/OpenAM/IDPSloRedirect/metaAlias/idp"/> 
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8081/OpenAM/IDPSloPOST/metaAlias/idp" ResponseLocation="http://localhost:8081/OpenAM/IDPSloPOST/metaAlias/idp"/> 
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/IDPSloSoap/metaAlias/idp"/> 
    <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8081/OpenAM/IDPMniRedirect/metaAlias/idp" ResponseLocation="http://localhost:8081/OpenAM/IDPMniRedirect/metaAlias/idp"/> 
    <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8081/OpenAM/IDPMniPOST/metaAlias/idp" ResponseLocation="http://localhost:8081/OpenAM/IDPMniPOST/metaAlias/idp"/> 
    <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/IDPMniSoap/metaAlias/idp"/> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:2.0:nameid-format:persistent 
    </NameIDFormat> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:2.0:nameid-format:transient 
    </NameIDFormat> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress 
    </NameIDFormat> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified 
    </NameIDFormat> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName 
    </NameIDFormat> 
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat> 
    <NameIDFormat> 
    urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName 
    </NameIDFormat> 
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8081/OpenAM/SSORedirect/metaAlias/idp"/> 
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8081/OpenAM/SSOPOST/metaAlias/idp"/> 
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/SSOSoap/metaAlias/idp"/> 
    <NameIDMappingService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/NIMSoap/metaAlias/idp"/> 
    <AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8081/OpenAM/AIDReqSoap/IDPRole/metaAlias/idp"/> 
    <AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:URI" Location="http://localhost:8081/OpenAM/AIDReqUri/IDPRole/metaAlias/idp"/> 
    </IDPSSODescriptor> 
    </EntityDescriptor> 

私は、このエラーは通常、何らかの方法でEntityIDsの不一致によって引き起こされる問題に

+0

あなたのIDPとSPのメタデータを投稿してください。 – blur0224

+0

@ blur0224 SPとIDPのメタデータを更新しました –

+0

これをチェックしましたか? https://github.com/ulisesbocchio/spring-boot-security-saml。 Spring BootとSAMLの間で設定を簡単にする – Ulises

答えて

0

を解決してください。あなたのメタデータが正しく設定されているように見えるので、探してみたところ、thisが見つかりました。

要求の送信と応答の受信中に、アプリケーションが同じHttpSessionを使用していることを確認してください。通常、この問題は、認証要求がローカルホストアドレスまたはHTTPスキームから初期化され、応答がパブリックホスト名またはhttpsスキームで受信される場合に発生します。たとえば、URL https://host:port/app/saml/loginからの認証を初期化するときには、応答はであり、http://host:port/app/saml/SSOまたはhttps://localhost:port/app/saml/SSOではありません。次のように

InResponseToFieldのチェックは、再構成し、コンテキストプロバイダによって無効にすることができます。

<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"> 
    <property name="storageFactory"> 
    <bean class="org.springframework.security.saml.storage.EmptyStorageFactory"/> 
    </property> 
</bean> 

あなたは、これは開発目的のためのみに使用されるべきであることに注意してください。安全性が低いため、この設定をローカルで有効にするには、おそらくSpring Profilesを使用するべきです。

関連する問題