简体   繁体   中英

How to set WebSSOProfileConsumerImpl in your Spring Configuration file

I am facing issue of specifying WebSSOProfileConsumerImpl to my Spring Configuration file. I am trying to modify responseSkew in this bean but after adding configuration for WebSSOProfileConsumerImpl I am getting MetadataManager issue


APPLICATION FAILED TO START


Description:

Parameter 0 of method setMetadata in org.springframework.security.saml.websso.AbstractProfileBase required a bean of type 'org.springframework.security.saml.metadata.MetadataManager' that could not be found.

Action:

Consider defining a bean of type 'org.springframework.security.saml.metadata.MetadataManager'

Can anyone help me in resolving this issue?

I have already gone through the link : http://docs.spring.io/spring-security-saml/docs/current/reference/html/configuration-advanced.html but it does not specify how to set this in configuration.

My Code

    import static org.springframework.security.extensions.saml2.config.SAMLConfigurer.saml;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml.websso.WebSSOProfileConsumer;
import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl;

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Value("${security.saml2.metadata-url}")
    String metadataUrl;

    @Value("${server.ssl.key-alias}")
    String keyAlias;

    @Value("${server.ssl.key-store-password}")
    String password;

    @Value("${server.port}")
    String port;

    @Value("${server.ssl.key-store}")
    String keyStoreFilePath;

    @Value("${security.saml2.responseSkew}")
    int responseSkew = 0;


    @Override
    protected void configure(final HttpSecurity http) throws Exception {

        http
            .authorizeRequests()
                .antMatchers("/saml*").permitAll()
                .anyRequest().authenticated()
                .and()
            .apply(saml())
                .serviceProvider()
                    .keyStore()
                        .storeFilePath(this.keyStoreFilePath)
                        .password(this.password)
                        .keyname(this.keyAlias)
                        .keyPassword(this.password)
                        .and()
                    .protocol("https")
                    .hostname(String.format("%s:%s", "localhost", this.port))
                    .basePath("/")
                    .and()
                .identityProvider()
                .metadataFilePath(this.metadataUrl).and();

       /* Map<? extends Object, Object> sharedObjects = new Map<? extends Object>, Object>(http.getSharedObjects());
        sharedObjects.put(WebSSOProfileConsumer.class, webSSOprofileConsumerImpl());*/

    }

    @Bean
    @Qualifier("webSSOprofileConsumer")
    public WebSSOProfileConsumer webSSOprofileConsumerImpl() {
        WebSSOProfileConsumerImpl consumerImpl = new WebSSOProfileConsumerImpl();
        consumerImpl.setResponseSkew(this.responseSkew);
        return consumerImpl;
    } 

}

If you do not need the WebSSOProfileConsumer to be accessible as a bean to the rest of the application, you can create it inside the configure method like this:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    WebSSOProfileConsumerImpl consumerImpl = new WebSSOProfileConsumerImpl();
    consumerImpl.setResponseSkew(this.responseSkew);

    http
        .authorizeRequests()
            .antMatchers("/saml*").permitAll()
            .anyRequest().authenticated()
            .and()
        .apply(saml())
            .serviceProvider()
                .ssoProfileConsumer(consumerImpl)  // <-- added here
                .keyStore()
                // Your method continues as before

I do not remember the exact reason regular wiring fails in your case, but the gist of it is that configure sets up a builder object rather than regular beans. Normally the ServiceProviderBuilder provides the MetadataManager needed by your WebSSOProfileConsumer during its build step, but if you autowire the profile consumer you won't get the MetadataManager provided for you since your autowired object is assumed to be complete already.

(I learned this when looking for a way to configure the max authentication age, since the two hour default in spring-security-saml in some cases is lower than the defaults used by identity providers. This effectively locks your users out of your application until the identity provider's max authentication age has passed.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM