首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在中使用XwsSecurityInterceptor时使用Spring安全身份验证失败的春季引导

在中使用XwsSecurityInterceptor时使用Spring安全身份验证失败的春季引导
EN

Stack Overflow用户
提问于 2015-06-05 11:16:12
回答 1查看 3.3K关注 0票数 1

我已经设置了一个spring引导(1.2.3)应用程序,其中包含了spring安全性和spring。我已经将spring安全性配置为在我的WebSecurityConfigurerAdapter中使用.ldapAuthentication()进行身份验证。我正在尝试获得相同的spring安全authenticationManager,以便在我的WsConfigurerAdapter中使用ws-security usernametokens (纯文本)来验证我的spring web服务。

我已经将我的WebSecurityConfigurerAdapter配置如下:

代码语言:javascript
复制
package za.co.switchx.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @ConfigurationProperties(prefix="ldap.contextSource")
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        return contextSource;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userSearchBase("cn=Users,dc=SwitchX,dc=co,dc=za")
                .userSearchFilter("(uid={0})")
                .groupSearchBase("cn=Groups,dc=SwitchX,dc=co,dc=za")
                .groupSearchFilter("(&(cn=*)(|    (objectclass=groupofUniqueNames)(objectclass=orcldynamicgroup)))")
                .contextSource(contextSource());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/ws/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
            .httpBasic();
    }   
}

于是,我就像这样配置了我的WsConfigurerAdapter:

代码语言:javascript
复制
package za.co.switchx.config;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
import org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor;
import org.springframework.ws.soap.security.xwss.callback.SpringPlainTextPasswordValidationCallbackHandler;

import org.springframework.ws.server.EndpointInterceptor;

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "ApplicantTypeService")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema applicantTypeServiceSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("ApplicantTypePort");
        wsdl11Definition.setLocationUri("/ws/ApplicantTypeService");
        wsdl11Definition.setTargetNamespace("http://switchx.co.za/services/applicant/types/applicant-type-web-service");
        wsdl11Definition.setSchema(applicantTypeServiceSchema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema applicantTypeSchema() {
        return new SimpleXsdSchema(new ClassPathResource("xsd/ApplicantTypeService.xsd"));
    }

    @Bean
    public XwsSecurityInterceptor securityInterceptor() {

        XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
        securityInterceptor.setCallbackHandler(new SpringPlainTextPasswordValidationCallbackHandler());
        securityInterceptor.setPolicyConfiguration(new ClassPathResource("securityPolicy.xml"));
        return securityInterceptor;
    }

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(securityInterceptor());
    }
}

如果我在SimplePasswordValidationCallbackHandler中使用XwsSecurityInterceptor,它会正确地对ws usernametoken进行身份验证,因此我知道ws-security部分没有什么问题。如果我通过http登录,它将正确地对ldap用户进行身份验证,因此我知道这是可行的。

问题是,当我尝试在ws安全usernametoken中使用ldap用户登录时,我在日志中获得了ERROR c.s.xml.wss.logging.impl.filter - WSS1408: UsernameToken Authentication Failed,因此看起来它不使用在WebSecurityConfigAdapter中定义的全局ldap身份验证。

我似乎想不出如何使(应该使用spring安全)在XwsSecurityInterceptor中使用全局authenticationManager,请帮助??在最后一天,我一直在为这件事大发雷霆,但似乎赢不了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-08 10:53:25

好的,我想出了这个问题,所以我会为将来尝试这个的人发帖子。

通过将spring引导类更改为:

代码语言:javascript
复制
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SwitchxApplication extends WebMvcConfigurerAdapter {

    @SuppressWarnings("unused")
    private static final Logger log = LoggerFactory.getLogger(SwitchxApplication.class);

    @Bean
    public ApplicationSecurity applicationSecurity() {
        return new ApplicationSecurity();
    }

    @Configuration
    @Order(Ordered.HIGHEST_PRECEDENCE)
    protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {              

        @Bean
        @ConfigurationProperties(prefix="ldap.contextSource")
        public LdapContextSource contextSource() {
            LdapContextSource contextSource = new LdapContextSource();
            return contextSource;
        }

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .ldapAuthentication()
                    .userSearchBase("cn=Users,dc=Blah,dc=co,dc=za")
                    .userSearchFilter("(uid={0})")
                    .groupSearchBase("cn=Groups,dc=Blah,dc=co,dc=za")
                    .groupSearchFilter("(&(cn=*)(|(objectclass=groupofUniqueNames)(objectclass=orcldynamicgroup)))")
                    .contextSource(contextSource());
        }
    }

@Order(Ordered.LOWEST_PRECEDENCE - 8)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {       

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .antMatchers("/ws/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
        .httpBasic();
    }       
}

    public static void main(String[] args) {
        SpringApplication.run(SwitchxApplication.class, args);
    }
}

然后在我的WsConfigurerAdapter中做了以下相关的更改:

代码语言:javascript
复制
@EnableWs
@Configuration  
public class WebServiceConfig extends WsConfigurerAdapter {

    private static final Logger log = LoggerFactory.getLogger(WebServiceConfig.class);

    @Autowired
    private AuthenticationManager authenticationManager;

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    .....
    .....

    @Bean
    public SpringPlainTextPasswordValidationCallbackHandler callbackHandler() {
        SpringPlainTextPasswordValidationCallbackHandler callbackHandler = new SpringPlainTextPasswordValidationCallbackHandler();
        try { 
            callbackHandler.setAuthenticationManager(authenticationManager);
        } catch(Exception e) {
            log.error(e.getMessage());
        }
        return callbackHandler;
    }

    @Bean
    public XwsSecurityInterceptor securityInterceptor() {

        XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
        securityInterceptor.setCallbackHandler(callbackHandler());
        securityInterceptor.setPolicyConfiguration(new ClassPathResource("securityPolicy.xml"));
        return securityInterceptor;
    }

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(securityInterceptor());
    }
}

因此,基本上最终的结果是,对于所有的/ws路径,基本的http安全性都被忽略了,但是由于allowing中的安全拦截器,它将使用一个基本的WS -安全用户名令牌来验证web服务调用,允许您使用使用ldap建立的spring安全性的两种身份验证机制。

我希望这对某些人有所帮助,因为在这个特定的设置上没有找到很多关于启动和java配置的文档,因为它仍然是比较新的。但是,在没有得到这个工作,这是相当棒,我非常印象深刻。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30665163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档