我试图从 Spring websocket SessionConnectEvent 获取主体用户名,但它在每个侦听器上均为空。我可能做错了什么?
为了实现它,我遵循了您可以在这里找到的答案:如何使用 Spring 4 捕获 webSocket 服务器中的连接事件?
@Slf4j
@Service
public class SessionEventListener {
@EventListener
private void handleSessionConnect(SessionConnectEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
@EventListener
private void handleSessionConnected(SessionConnectEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
@EventListener
private void handleSubscribeEvent(SessionSubscribeEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String subscriptionId = headers.getSubscriptionId();
log.debug("subscriptionId is " + subscriptionId);
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
@EventListener
private void handleUnsubscribeEvent(SessionUnsubscribeEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String subscriptionId = headers.getSubscriptionId();
log.debug("subscriptionId is " + subscriptionId);
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
@EventListener
private void handleSessionDisconnect(SessionDisconnectEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
log.debug("sessionId is " + event.getSessionId());
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
}
这是我的安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.permitAll()
.and().csrf().disable();
}
}
由于我没有实现身份验证机制,Spring 没有足够的信息来提供主体用户名。所以我要做的就是配置一个生成主体的 HandshakeHandler。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
public static final String ENDPOINT_CONNECT = "/connect";
public static final String SUBSCRIBE_USER_PREFIX = "/private";
public static final String SUBSCRIBE_USER_REPLY = "/reply";
public static final String SUBSCRIBE_QUEUE = "/queue";
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker(SUBSCRIBE_QUEUE, SUBSCRIBE_USER_REPLY);
registry.setUserDestinationPrefix(SUBSCRIBE_USER_PREFIX);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(ENDPOINT_CONNECT)
// assign a random username as principal for each websocket client
// this is needed to be able to communicate with a specific client
.setHandshakeHandler(new AssignPrincipalHandshakeHandler())
.setAllowedOrigins("*");
}
}
/**
* Assign a random username as principal for each websocket client. This is
* needed to be able to communicate with a specific client.
*/
public class AssignPrincipalHandshakeHandler extends DefaultHandshakeHandler {
private static final String ATTR_PRINCIPAL = "__principal__";
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
final String name;
if (!attributes.containsKey(ATTR_PRINCIPAL)) {
name = generateRandomUsername();
attributes.put(ATTR_PRINCIPAL, name);
} else {
name = (String) attributes.get(ATTR_PRINCIPAL);
}
return new Principal() {
@Override
public String getName() {
return name;
}
};
}
private String generateRandomUsername() {
RandomStringGenerator randomStringGenerator =
new RandomStringGenerator.Builder()
.withinRange('0', 'z')
.filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS).build();
return randomStringGenerator.generate(32);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)