より良い解決策は見つかりませんでしたが、これは私にとってはうまくいきます。
JMS メッセージを送信することでAuthentication
ヘッダーとして保存し、それぞれ受信してセキュリティ コンテキストを再作成します。Authentication
ヘッダーとして保存するには、次のようにシリアル化する必要がありBase64
ます。
class AuthenticationSerializer {
static String serialize(Authentication authentication) {
byte[] bytes = SerializationUtils.serialize(authentication);
return DatatypeConverter.printBase64Binary(bytes);
}
static Authentication deserialize(String authentication) {
byte[] decoded = DatatypeConverter.parseBase64Binary(authentication);
Authentication auth = (Authentication) SerializationUtils.deserialize(decoded);
return auth;
}
}
設定した Message ヘッダーを送信するだけで、Message Template 用の Decorator を作成でき、自動的に行われます。デコレータでは、そのようなメソッドを呼び出すだけです:
private void attachAuthenticationContext(Message message){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String serialized = AuthenticationSerializer.serialize(auth);
message.setStringProperty("authcontext", serialized);
}
受信は複雑になりますが、自動で行うこともできます。適用する代わりに、@EnableJMS
次の構成を使用します。
@Configuration
class JmsBootstrapConfiguration {
@Bean(name = JmsListenerConfigUtils.JMS_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public JmsListenerAnnotationBeanPostProcessor jmsListenerAnnotationProcessor() {
return new JmsListenerPostProcessor();
}
@Bean(name = JmsListenerConfigUtils.JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME)
public JmsListenerEndpointRegistry defaultJmsListenerEndpointRegistry() {
return new JmsListenerEndpointRegistry();
}
}
class JmsListenerPostProcessor extends JmsListenerAnnotationBeanPostProcessor {
@Override
protected MethodJmsListenerEndpoint createMethodJmsListenerEndpoint() {
return new ListenerEndpoint();
}
}
class ListenerEndpoint extends MethodJmsListenerEndpoint {
@Override
protected MessagingMessageListenerAdapter createMessageListenerInstance() {
return new ListenerAdapter();
}
}
class ListenerAdapter extends MessagingMessageListenerAdapter {
@Override
public void onMessage(Message jmsMessage, Session session) throws JMSException {
propagateSecurityContext(jmsMessage);
super.onMessage(jmsMessage, session);
}
private void propagateSecurityContext(Message jmsMessage) throws JMSException {
String authStr = jmsMessage.getStringProperty("authcontext");
Authentication auth = AuthenticationSerializer.deserialize(authStr);
SecurityContextHolder.getContext().setAuthentication(auth);
}
}