在SecurityContext错误中找不到接收身份验证对象

时间:2019-05-14 15:05:21

标签: authentication soap spring-security ldap security-context

开始在新的Spring Boot 1.5.9应用程序上工作,该应用程序接收到一个肥皂请求,该请求需要针对LDAP,令牌验证和一些时间戳限制进行身份验证。每当我尝试将@PreAuthorize添加到我的端点时,都会出现“在SecurityContext中找不到身份验证对象”错误。

当前通过通过SoapUI发送消息并运行本地服务器进行测试。

我已将日志级别设置为TRACE,但仍然没有日志记录。

当我从端点中删除@PreAuthorize批注时,我确实在SoapUI中收到了正确的响应,但是那当然是不进行身份验证的。

@Endpoint
public class WidgetEndpoint {
private static final Logger LOGGER = LoggerFactory.getLogger(WidgetEndpoint.class);

public static final String NAMESPACE_URI = "http://www.widget.com/ws/widget";

public static final String NAMESPACE_URI_GD = "urn:Connect.WidgetApp/WSDL";

@PayloadRoot(namespace = NAMESPACE_URI_GD, localPart = "widgetGDRq")
@ResponsePayload
@PreAuthorize("hasRole('ROLE_ACCESS')")
public WidgetGDRs widgetGD(@RequestPayload WidgetGDRq request) {

    LOGGER.info("Request Received: " + request.getData());

    ObjectFactory factory = new ObjectFactory();
    WidgetFormsGDRs response = factory.createWidgetGDRs();
    response.setData("Congrates! You got Data: " + request.getData());
    return response;
}

}

@EnableWs
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class WebServiceConfig extends WsConfigurerAdapter {


 @Value("${ldap.ur}")
 @Value("${ldap.userName}")
 @Value("${ldap.password}")
 @Value("${ldap.baseDN}")

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

@Bean(name = "widget")
public Wsdl11Definition defaultWsdl11Definition() {
    SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
    wsdl11Definition.setWsdl(new ClassPathResource("/ws/WidgetApp.wsdl"));

    return wsdl11Definition;
}

public List<String> ldapURL() {
    List<String> ldapUrlList = new ArrayList<String>();
    ldapUrlList.add(ldapURL);
    return ldapUrlList;
}

@Bean
public DefaultSpringSecurityContextSource ldapContextSource() {
    DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapURL(),
            ldapBaseDN);
    contextSource.setDirObjectFactory(CustomDirObjectFactory.class);
    contextSource.setUserDn(ldapUserDN);
    contextSource.setPassword(ldapPassword);
    contextSource.setPooled(true);
    return contextSource;
}

@Bean
public FilterBasedLdapUserSearch ldapUserSearch() {
    FilterBasedLdapUserSearch filterBasedLdapUserSearch = new FilterBasedLdapUserSearch("", "(uid={0})",
            ldapContextSource());
    return filterBasedLdapUserSearch;
}

@Bean
public DefaultLdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
    DefaultLdapAuthoritiesPopulator defaultLdapAuthoritiesPopulator = new DefaultLdapAuthoritiesPopulator(
            ldapContextSource(), "ou=Roles");
    defaultLdapAuthoritiesPopulator.setGroupRoleAttribute("cn");
    defaultLdapAuthoritiesPopulator.setGroupSearchFilter("(uniquemember={0})");
    return defaultLdapAuthoritiesPopulator;
}

@Bean
public LdapUserDetailsService ldapUserDetailsService() {
    LdapUserDetailsService ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch(),
            ldapAuthoritiesPopulator());
    return ldapUserDetailsService;
}

@Bean
public BindAuthenticator ldapBindAuthenticator() {
    BindAuthenticator authinticator = new BindAuthenticator(ldapContextSource());
    authinticator.setUserSearch(ldapUserSearch());
    return authinticator;
}

@Bean
public LdapAuthenticationProvider ldapAuthenticationProvider() {
    LdapAuthenticationProvider ldapAuthProvider = new LdapAuthenticationProvider(ldapBindAuthenticator(),
            ldapAuthoritiesPopulator());
    return ldapAuthProvider;

}

@Bean
public ProviderManager ldapAuthenticationManager() {
    List<AuthenticationProvider> ldapProviderList = new ArrayList<AuthenticationProvider>();
    ldapProviderList.add(ldapAuthenticationProvider());
    ProviderManager ldapProviderManager = new ProviderManager(ldapProviderList);
    return ldapProviderManager;
}

@Bean
public CallbackHandler ldapSecurityHandler() {
    SimplePasswordValidationCallbackHandler handler = new SimplePasswordValidationCallbackHandler();
    handler.setUsersMap(Collections.singletonMap(ldapUserDN, ldapPassword));
    return handler;
}

@Bean
public SoapFaultMappingExceptionResolver exceptionResolver() {
    SoapFaultMappingExceptionResolver soapFaultMappingExceptionResolver = new SoapFaultMappingExceptionResolver();
    SoapFaultDefinition defaultDefinition = new SoapFaultDefinition();
    defaultDefinition.setFaultCode(SoapFaultDefinition.SERVER);
    soapFaultMappingExceptionResolver.setDefaultFault(defaultDefinition);
    Properties errorMappings = new Properties();
    errorMappings.setProperty("org.springframework.ws.soap.security.wss4j.Wss4jSecurityValidationException=CLIENT",
            "Timestamp and/or user credentials are invalid and/or missing");
    errorMappings.setProperty("org.springframework.security.core.AuthenticationException=CLIENT",
            "User authentication failed");
    errorMappings.setProperty("org.springframework.security.access.AccessDeniedException=CLIENT",
            "User authorization failed");
    errorMappings.setProperty("java.lang.Exception=SERVER", "Problem waiting for a response");
    soapFaultMappingExceptionResolver.setExceptionMappings(errorMappings);

    return soapFaultMappingExceptionResolver;

}

@Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() {
    Wss4jSecurityInterceptor wssjInt = new Wss4jSecurityInterceptor();
    wssjInt.setValidationActions(WSConstants.TIMESTAMP_TOKEN_LN + " " +  WSConstants.USERNAME_TOKEN_LN );
    wssjInt.setValidationActions("Timestamp");
    wssjInt.setTimestampStrict(true);
    wssjInt.setValidationTimeToLive(3000);
    wssjInt.setValidationCallbackHandler(ldapSecurityHandler());
    wssjInt.setExceptionResolver(exceptionResolver());

    return wssjInt;
}

@Bean
public AnnotationActionEndpointMapping annotationActionEndpointMapping() {

    AnnotationActionEndpointMapping aaeMapping = new AnnotationActionEndpointMapping();
    aaeMapping.setPreInterceptors(new EndpointInterceptor[] { wss4jSecurityInterceptor() });
    return aaeMapping;
}

}

更新:

我已经取得了一些进步,但是仍然遇到相同的错误。我在配置中添加了拦截器

@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
    LOGGER.info("addInterceptors");
    interceptors.add(wss4jSecurityInterceptor());
}

我已将trace选项添加到我的application.propeties文件中,可以看到正在从LDAP中检索角色

2019-05-15 13:24:16.247调试5576 --- [nio-8080-exec-6] .s.s.l.u.DefaultLdapAuthoritiesPopulator:搜索角色:[ROLE_ACCESS,ROLE_WRITE] 2019-05-15 13:24:16.247调试5576 --- [nio-8080-exec-6] ossluLdapUserDetailsMapper:使用DN从上下文映射用户详细信息: ,*** 2019-05-15 13:24:16.247 WARN 5576 --- [nio-8080-exec-6] o.s.w.s.s.w.Wss4jSecurityInterceptor:无法验证请求:无法对安全令牌进行身份验证或授权;嵌套的异常是org.apache.wss4j.common.ext.WSSecurityException:无法对安全令牌进行身份验证或授权

0 个答案:

没有答案