当前位置: 首页 > 知识库问答 >
问题:

Spring SAML 2.0-使用https制作endpoint

江洲
2023-03-14

我正在尝试在我的端实现SAML(它将用作SP)。
作为测试过程的一部分,我尝试使用AD(AD FS)来测试我的端。(Windows Server 2012 R2)。
正如我在这里读到的-AD FS需要HTTPS终结点。我尝试使用SamlContextProviderLB但没有成功。所以我有两个问题:

    null

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true)
    @ComponentScan(basePackages = { "com.wss.service.saml" /* , "org.springframework.security.saml" */} )
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        public static final String WSS_SAML_LOGIN_SERVLET = "/Wss/samlLogin";
        private static final int HOURS_ALLOWED_FROM_PREVIOUS_LOGIN = 2;

        @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() {
    //        return new SAMLContextProviderImpl();
            SAMLContextProviderLB providerLB = new SAMLContextProviderLB();
            providerLB.setScheme("https");
            providerLB.setServerPort(8443);
            providerLB.setServerName("MyServerName");
            providerLB.setContextPath("/context");
            return providerLB;
        }

        // 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() {
            WebSSOProfileConsumerImpl profileConsumer = new WebSSOProfileConsumerImpl();
            int secondsPromPreviousLogin = HOURS_ALLOWED_FROM_PREVIOUS_LOGIN * 3600;
            profileConsumer.setMaxAuthenticationAge(secondsPromPreviousLogin);
            return profileConsumer;
        }

        // 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 passwords = new HashMap();
            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.setFilterProcessesUrl("/Wss/login");
            samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions());
            return samlEntryPoint;
        }

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

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

        @Bean
        @Qualifier("idp-ssocircle")
        public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider()
                throws MetadataProviderException {
            String idpSSOCircleMetadataURL = "https://idp.ssocircle.com/idp-meta.xml";
            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("adfs")
        public ExtendedMetadataDelegate adfsExtendedMetadataProvider()
            throws MetadataProviderException {
            Timer backgroundTaskTimer = new Timer(true);
            ClasspathResource resource;
            try {
                resource = new ClasspathResource("/metadata/FederationMetadata.xml");
            } catch (ResourceException e) {
                return null;
            }
            ResourceBackedMetadataProvider provider =
                    new ResourceBackedMetadataProvider(backgroundTaskTimer, resource);
            ExtendedMetadataDelegate extendedMetadataDelegate =
                    new ExtendedMetadataDelegate(provider);

            extendedMetadataDelegate.setMetadataTrustCheck(false);
            return extendedMetadataDelegate;
        }

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

        // Filter automatically generates default SP metadata
        @Bean
        public MetadataGenerator metadataGenerator() {
            MetadataGenerator metadataGenerator = new MetadataGenerator();
            metadataGenerator.setEntityId("com:asaf:saml:sp");
            metadataGenerator.setEntityBaseURL("http://localhost:8080");
            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(WSS_SAML_LOGIN_SERVLET);
    //        successRedirectHandler.setTargetUrlParameter("RelayState");
            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();
    //        SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilterExtension();
            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);
            // TODO - Logout from WSS session
            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 bindings = new ArrayList();
            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 chains = new ArrayList();
            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("/error").permitAll()
                .antMatchers("/saml/**").permitAll()
                .antMatchers("/Wss/**").permitAll()
                .anyRequest().authenticated();
            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());
        }   

    }

谢谢!

共有1个答案

邹祺然
2023-03-14

参照这里的API文档

您可以将以下内容添加到configure(HttpSecurity)方法中的任何http构建器中。

.and()
 .requiresChannel()
 .anyRequest().requireSecure(); //will force https
 类似资料:
  • 问题内容: 如何使用PHP中特定的.htaccess和mod_rewrite页面强制使用SSL / https。 问题答案: 对于Apache,您可以使用强制SSL : 除非为当前连接启用了SSL上的HTTP(即HTTPS),否则该指令禁止访问。这在启用SSL的虚拟主机或目录中非常方便,可防止配置错误暴露应受保护的内容。使用此指令时,将拒绝所有未使用SSL的请求。 不过,这不会重定向到https。

  • 使用 HTTPS HTTPS 即 HTTP over SSL/TLS,是 HTTP 的安全版本,在 HTTP 上加了一层处理加密信息的模块。 SSL/TLS 全称安全传输层协议 Transport Layer Security, 是介于 TCP 和 HTTP 之间的一层安全协议,不影响原有的 TCP 协议和 HTTP 协议,所以使用 HTTPS 基本上不需要对 HTTP 页面进行太多的改造。浏览器

  • 我的eclipse安装始终使用https协议下载存储库结构。问题是我的合作代理不允许我在这个url上使用https。如何强制m2e使用http? 我尝试了m2e的不同外部maven安装,但没有成功。只有在使用CLI中的外部maven(使用http)时,它才起作用。

  • 我正在尝试构建react原生android应用程序,作为一种依赖,我看到我有gradle,但它无法在构建时加载。错误消息: 问题很明显,我坐在公司代理后面,阻止任何像这样的错误HTTPS连接。所以我的问题是:如何强制gradle使用HTTP加载这些文件?这些属性应该放在哪里(哪一个gradle文件,即gradle.properties)? P. S.我已经在gradle属性文件中设置了这些: 任何

  • 我有项目,我在ubuntu服务器上安装了SSL证书。我已经做了我发现的每一个解决方案,但每次打开页面时仍然会收到这条消息。 以下是我为强制Laravel使用https所做的更改: 我变了。htaccess在我的公用文件夹中,并添加了以下行 2-应用程序内- 3-我创建了php artisan make:middleware ForceSSL,并将以下代码添加到句柄函数中 在内核中。php 在里面e

  • 问题内容: 我正在尝试为Express.js创建一个中间件,以将所有非安全(端口80)通信重定向到安全SSL端口(443)。不幸的是,Express.js请求中没有任何信息可让您确定该请求是否来自http或https。 一种解决方案是重定向 每个 请求,但这不是我的选择。 笔记: 没有可能用Apache或其他东西来处理它。它 必须 在节点中完成。 应用程序中只能启动 一台 服务器。 您将如何解决?