spring 带有摘要认证的 websocket
spring websocket with digest authentication
我使用 Spring 安全性 来验证我的 spring websocket
服务器。它在 Basic authentication
上工作正常,但当我更改为 Digest authentication
时却出错了。我不知道要在 headers 中放入什么。有人知道任何解决方案吗?
这是 websocket 客户端代码片段:
SockJsClient sockJsClient;
WebSocketStompClient stompClient;
List<Transport> transports = new ArrayList<>();
final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4=");
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
sockJsClient = new SockJsClient(transports);
stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
......
更新:
它与 digest for rest 配合使用效果很好,以下代码可以配置 RestTempalte
使用 digest:
import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {
public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpClient client) {
super(client);
}
@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
return createHttpContext(uri);
}
private HttpContext createHttpContext(URI uri) {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the local auth cache
DigestScheme digestAuth = new DigestScheme();
// If we already know the realm name
digestAuth.overrideParamter("realm", "myrealm");
HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());
authCache.put(targetHost, digestAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localcontext;
}
}
获取休息模板:
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
public class RestTempleteConfig {
public RestTemplate getRestTemplate() {
CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider())
.useSystemProperties().build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryDigestAuth(
client);
return new RestTemplate(requestFactory);
}
private CredentialsProvider provider() {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("admin", "admin");
provider.setCredentials(AuthScope.ANY, credentials);
return provider;
}
}
使用休息模板:
RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();
String uri = "http://localhost:8080/login";
ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
System.out.println(entity.getBody());
我找到解决办法了。在服务器端配置 digest authentication
和 spring security
,然后将客户端实现更改为:
RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();
SockJsClient sockJsClient;
WebSocketStompClient stompClient;
List<Transport> transports = new ArrayList<>();
final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
StandardWebSocketClient websocketClient = new StandardWebSocketClient();
// add restTemplate first
transports.add(new RestTemplateXhrTransport(restTemplate));
transports.add(new WebSocketTransport(websocketClient));
sockJsClient = new SockJsClient(transports);
stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
摘要配置在rest template
,我们需要做的是将其添加到Transport list
。您应该先添加 rest template
,然后添加 websocket
,因为这在创建 sockJs
url 时很重要。更多详情参考.
我使用 Spring 安全性 来验证我的 spring websocket
服务器。它在 Basic authentication
上工作正常,但当我更改为 Digest authentication
时却出错了。我不知道要在 headers 中放入什么。有人知道任何解决方案吗?
这是 websocket 客户端代码片段:
SockJsClient sockJsClient;
WebSocketStompClient stompClient;
List<Transport> transports = new ArrayList<>();
final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4=");
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
sockJsClient = new SockJsClient(transports);
stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
......
更新:
它与 digest for rest 配合使用效果很好,以下代码可以配置 RestTempalte
使用 digest:
import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {
public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpClient client) {
super(client);
}
@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
return createHttpContext(uri);
}
private HttpContext createHttpContext(URI uri) {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the local auth cache
DigestScheme digestAuth = new DigestScheme();
// If we already know the realm name
digestAuth.overrideParamter("realm", "myrealm");
HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());
authCache.put(targetHost, digestAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localcontext;
}
}
获取休息模板:
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
public class RestTempleteConfig {
public RestTemplate getRestTemplate() {
CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider())
.useSystemProperties().build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryDigestAuth(
client);
return new RestTemplate(requestFactory);
}
private CredentialsProvider provider() {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("admin", "admin");
provider.setCredentials(AuthScope.ANY, credentials);
return provider;
}
}
使用休息模板:
RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();
String uri = "http://localhost:8080/login";
ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
System.out.println(entity.getBody());
我找到解决办法了。在服务器端配置 digest authentication
和 spring security
,然后将客户端实现更改为:
RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();
SockJsClient sockJsClient;
WebSocketStompClient stompClient;
List<Transport> transports = new ArrayList<>();
final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
StandardWebSocketClient websocketClient = new StandardWebSocketClient();
// add restTemplate first
transports.add(new RestTemplateXhrTransport(restTemplate));
transports.add(new WebSocketTransport(websocketClient));
sockJsClient = new SockJsClient(transports);
stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
摘要配置在rest template
,我们需要做的是将其添加到Transport list
。您应该先添加 rest template
,然后添加 websocket
,因为这在创建 sockJs
url 时很重要。更多详情参考