Что делать? У меня есть
- сервис Soap, выполненный с использованием Java 17 + Spring Boot 3.3.3
- .cer, который использует мой клиент. для подписи запроса
- .cer и .key моего собственного сертификата
- файла .p12 и файла .jks, созданных с помощью команд из Chatgpt< /li>
- Использовать WS-Security из Spring Boot с классом Wss4jSecurityInterceptor.
- Захватите исходящее сообщение SOAP в SoapEndpointInterceptor и добавьте соответствующие поля.
Ни один из этих подходов мне не помог.
Ни один из этих подходов мне не помог.
p>
Сценарий 1:
После многих вопросов и тонких настроек с помощью моего чата-gpt/gemini все, что я получаю, это код с выдуманными методами или другими. это не делает то, что мне нужно. Я прочитал документацию библиотеки, и методы не объясняют, откуда брать значения и как их вычислять.
Поэтому я прибегаю к методу проб и ошибок, следуя имеющейся информации. Я передаю файл crypto.properties вместе с файлом .p12, содержащим мои .cer и .key с действительным паролем и псевдонимом. Я также пробовал использовать файл .jks, но в обоих случаях получаю такие ошибки, как «неопознанный символ 111» или что библиотека не была инициализирована должным образом.
В целом я стараюсь все методы класса, использующие форматы p12 и jks, а также файл crypto.properties, но служба либо не запускается, либо не может подписать, вместо этого отправляя ответ 202 с пустым телом в мою конечную точку.
Результат? Служба даже не запускается из-за вышеупомянутых ошибок.
Сценарий 2:
Используя то и это, я создаю все необходимые теги.
- BinarySecurityToken: я помещаю .cer преобразуется в base64 с использованием класса X.509Certificate.
- DigestMethod и SignatureMethod используют SHA-1 и SHA-1withRSA соответственно. .
- DigestValue: хэш SHA-1, сгенерированный из необработанного содержимого XML в виде строки из мыла:Body (он не включает само тело, только корневой элемент внутри него).
- SignatureValue: Используя Java-класс Signer, я извлекаю закрытый ключ из файла .p12, созданного на основе моего исходного .cer, и .key (тот же .cer, который используется в BinarySecurityToken), и я подписываю необработанную XML-строку элемента SignedInfo (включая самого себя и все его содержимое).
- Ссылка (внутри SecurityTokenReference) имеет атрибут URI, указывающий на атрибут wsu:Id в BinarySecurityToken (это UUID, который я создаю сам).
- Ссылка (вне SecurityTokenReference), основанная на примерах, которые я нашел в Интернете, имеет атрибут URI, указывающий на атрибут wsu:id, присутствующий в мыле:Body. Я также генерирую это с помощью UUID.
- Отметка времени: я просто устанавливаю текущее время со сроком действия на один час вперед.
Примечания:
- Нет , служба REST не является вариантом.
- Нет, отказ от использования этого стандарта не является вариантом; это нужно сделать так.
- Это нужно сделать в Java 17 + Spring Boot 3+.
Дополнительные примечания:
- Мне также нужно сделать наоборот (сервис будет использовать другой сервис мыла, мне нужно подписать запрос и проверить подпись ответа).
- Мне нужно добавить несколько пользовательских элементов XML в
@Configuration
@EnableWs
public class SoapService extends WsConfigurerAdapter {
// other soap-service-related beans like message dispatcher, marshaller, and so on.
@Bean
Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
try {
// check incoming certificate, this does produce an output similar to the ones on my cites, but not equal
interceptor.setSecurementActions(WSHandlerConstants.SIGNATURE);
interceptor.setValidationCallbackHandler(this.securityCallback());
// sign outgoing response
interceptor.setSecurementActions(WSHandlerConstants.SIGNATURE);
interceptor.setSecurementUsername("your_alias");
interceptor.setSecurementPassword("your_password");
interceptor.setSecurementSignatureCrypto(this.cryptoConfig().getObject());
} catch(Exception e) {
e.printStackTrace();
System.out.println("error while initializing interceptor");
}
return interceptor;
}
@Bean
CryptoFactoryBean cryptoConfig() throws IOException {
CryptoFactoryBean bean = new CryptoFactoryBean();
bean.setKeyStorePassword("your_password");
bean.setKeyStoreLocation(new ClassPathResource("certificate.jks"));
return bean;
}
@Bean
CallbackHandler securityCallback() {
// how am i supposed to check the .cer my client sends here?
return new SimplePasswordValidationCallbackHandler() {{
setUsers(new Properties() {
private static final long serialVersionUID = 3422928594124631515L;
{
setProperty("alias", "your_password");
}
});
}};
}
@Override
public void addInterceptors(List interceptors) {
interceptors.add(securityInterceptor());
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... -spring-ws
Мобильная версия