我已经使用Spring Boot实现了一个带有Spring Boot的小型websocket服务器,并使用Basic Auth通过Spring Security保护它。 Angular 2用于前端。我已经实现了以下解决方案来连接websocket。
* Connects to a websocket server. * @param {string} url The url of the WS Server * @param {string} channel The channel to subscribe * @return {boolean} connection status */ public connect(url: string, channel: string): boolean { console.group('WebSocketService: Welcome to the connect function.'); console.log('Connects to', url); console.log('Channel is', channel); let _self = this; let socket = new SockJS(url);
_self.wsClient = Stomp.over(socket);
_self.wsClient.connect({}, function(frame) {
_self.setConnected(true);
console.log('Connected: ', frame);
_self.wsClient.subscribe(channel, function(greeting) {
console.log(greeting);
_self.subjects[channel].next(greeting);
});
});
console.groupEnd();
return true;
}
调用此功能可让浏览器打开用户名和密码的输入。 现在我可以连接和断开服务器,无需再次输入用户名/密码。
如何使用代码中的登录信息替换此浏览器输入窗口?
我尝试通过以下单个Post请求执行此操作:
private test2(){ let username : string = 'admin'; let password : string = 'pass'; let headers = new Headers(); headers.append("Authorization", "Basic " + btoa(username + ":" + password)); headers.append("Content-Type", "application/x-www-form-urlencoded"); console.log('Test beginnt'); return this._http.get('http://localhost:8080/gs-guide-websocket', {headers: headers}).map(res=> console.log(res)) }
块引用
但这只给了我一个http 200响应,并没有打开会话或其他什么。
我也尝试将登录信息放在原始请求中。
_self.wsClient.connect(' admin','传递',功能(框架){...}
感谢您的帮助。
答案 0 :(得分:0)
我还没与SockJS合作过。但我已经为纯WebSocket实现了一些小机制。也许它会有所帮助
首先,OAUTH配置:
<div>
<ul class="uib-datepicker-popup dropdown-menu" dropdown-nested ng-if="isOpen" style="display: block" ng-style="{top: position.top+'px', left: position.left+'px'}" ng-keydown="keydown($event)" ng-click="$event.stopPropagation()">
<!-- regular price button -->
<button type="button" class="btn btn-sm btn-warning" ng-click="$parent.$parent.regularPrice()">Regular Price</button>
<!-- /regular price button-->
<li ng-transclude></li>
<li ng-if="showButtonBar" style="padding:10px 9px 2px" class="uib-button-bar">
<span class="btn-group pull-left">
<button type="button" class="btn btn-sm btn-info uib-datepicker-current" ng-click="select('today')" ng-disabled="isDisabled('today')">{{ getText('current') }}</button>
<button type="button" class="btn btn-sm btn-danger uib-clear" ng-click="select(null)">{{ getText('clear') }}</button>
</span>
<button type="button" class="btn btn-sm btn-success pull-right uib-close" ng-click="close($event)">{{ getText('close') }}</button>
</li>
</ul>
</div>
第二,angular2授权:
@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
private static Logger logger = LoggerFactory.getLogger(OAuth2Configuration.class);
private UsersService service = new UsersService();
@Autowired
AuthenticationManagerBuilder authenticationManager;
@Autowired
UserDetailsService userDetailsService;
@Override
public void configure( AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
authenticationManager.userDetailsService(this.userDetailsService);
endpoints.authenticationManager((Authentication authentication) -> authenticationManager.getOrBuild().authenticate(authentication));
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("application_name")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.scopes("write", "read", "trust")
.secret("secret").accessTokenValiditySeconds(24 * 60 * 60);
}
@Bean
public UserDetailsService userDetailsService() {
return (username) -> {
return service.getByName(username).map(account -> new User(account.getName(), account.getPassword(), account.getAuthorities())).orElseThrow(
() -> new RuntimeException("User not found")
);
};
}
}
第三个套接字配置:
let headers = new Headers();
headers.append("Authorization", "Basic appname:secret");
this.http.post("localhost:8080/oauth_endpoint?grant_type=password&scope=trust&username=" + login + "&password=" + password , "", { headers: headers })
.map((response: Response) => response.json())
.subscribe(response => {
this.accessToken = response.access_token; //will be used for socket
}
);
最后,通过angular2建立连接:
@Configuration
@EnableWebSocket
public class SocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(socketHandler(), "/websocket").setAllowedOrigins("*");
}
@Bean
public SocketHandler socketHandler() {
return new SocketHandler();
}
}
public class SocketHandler extends TextWebSocketHandler {
@Autowired
private CheckTokenEndpoint checkTokenEndpoint;
private static Logger logger = LoggerFactory.getLogger(SocketHandler.class);
public void afterConnectionEstablished(WebSocketSession session) {
logger.info("New peer connected: " + session.getId());
}
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
logger.debug("Peer is trying to authenticate");
String token = message.getPayload().toString();
try {
checkTokenEndpoint.checkToken(token);
logger.info("New peer authenticated. ");
} catch (Exception e) {
logger.warn("Peer unauthenticated!");
session.close(); //closing connection when provided token doesn't match
}
}
}
如果您只是复制/粘贴,此代码可能无效。我还有其他几个案例要处理(即我的websocket正在重新建立连接)。因为它们不在问题范围内,所以我在此处放置代码时手动删除它们。