Nano Hash - криптовалюты, майнинг, программирование

Spring WebSocket с дайджест-аутентификацией

Я использую Spring security для аутентификации своего spring websocket сервера. Он отлично работает с Basic authentication, но что-то пошло не так, когда я перешел на Digest authentication. Я не знаю, что вставить в заголовки. Кто-нибудь знает какие-нибудь решения?

Это фрагмент кода клиента 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());
......

Обновление:

Он хорошо работает с дайджестом для отдыха, следующие коды могут настроить RestTempalte для использования дайджеста:

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? Это не просто установка заголовка. 06.03.2017
  • Когда клиент отправляет запрос на сервер, он впервые получает ошибку 401. Затем клиент может получить область и одноразовый номер из заголовка ответа, чтобы отправить последующий запрос. Я думаю, что это может быть нормально, если я отправлю правильный заголовок, но трудно получить одноразовый номер. Но как правильно аутентифицировать веб-сокет с помощью дайджеста? 07.03.2017

Ответы:


1

Я понял решение. Настройте 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, так как это важно при создании URL-адреса sockJs. Дополнительные сведения см. по этой ссылке.

13.03.2017
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..