Работал над новым приложением Spring Boot 1.5.9, которое получает запрос мыла, который должен пройти аутентификацию на основе LDAP, проверку токена, а также некоторые ограничения на временные метки.Всякий раз, когда я пытаюсь добавить @PreAuthorize к моей конечной точке, я получаю сообщение об ошибке «Объект аутентификации не найден в SecurityContext».
В настоящее время проводится тестирование путем отправки сообщения через SoapUI и запуска локального сервера.
Я установил уровни журналов TRACE, но по-прежнему не веду журналы.
Я получаю правильный ответ в SoapUI, когда удаляю аннотацию @PreAuthorize из конечной точки, но затем, конечно,это не аутентификация.
@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());
}
Я добавил опцию трассировки в мой файл application.propeties и вижу, что роли извлекаются из LDAP
2019-05-15 13: 24: 16.247 DEBUG 5576 --- [nio-8080-exec-6] .ssluDefaultLdapAuthoritiesPopulator: роли из поиска: [ROLE_ACCESS, ROLE_WRITE] 2019-05-15 13: 24: 16.247 DEBUG 5576 --- [nio-8080-exec-6] ossluLdapUserDetailsMapper: отображение пользовательских данных из контекста с DN: , , *** 2019-05-15 13: 24: 16.247 WARN 5576 --- [nio-8080-exec-6] oswsswWss4jSecurityInterceptor: Не удалось проверить запрос: маркер безопасности не может быть аутентифицирован или авторизован;вложенное исключение: org.apache.wss4j.common.ext.WSSecurityException: маркер безопасности не может быть аутентифицирован или авторизован