У меня довольно упрощенная конфигурация Spring Security в моем веб-приложении Spring MVC. Я получаю REST-запросы от удаленного веб-приложения, которые аутентифицируются с помощью моего фильтра предварительной аутентификации. Я просто ищу заголовок в запросе и, если он присутствует, возвращаю это строковое значение (которое является именем пользователя) в качестве объекта аутентификации. Это отлично работает, и когда приходит запрос, пользователь проходит аутентификацию.
По какой-либо причине, каждый раз, когда я пытаюсь применить аннотированную безопасность antMatcher или метода контроллера на основе шаблона, это приводит к тому, что клиент получает ошибку CORS. Я должен держать доступ полностью открытым, чтобы фактический запрос мог выполняться в этой междоменной среде.
Моя проблема в том, что через некоторое время сеанс, кажется, истекает. Когда пользователь нажимает на один из моих контроллеров, и я пытаюсь получить имя пользователя из объекта Principal, я получаю исключение NullPointerException, потому что Principal имеет значение null. По истечении срока действия похоже, что AnonymousAuthFilter срабатывает и просто позволяет пользователю подключаться как анонимному.
Я предполагаю, что мне не нужен полностью сеанс аутентификации без сохранения состояния, потому что я также использую сеанс для веб-сокетов, и когда я использую свой шаблон обмена сообщениями для «convertAndSendToUser», мне нужно указать имя пользователя, а Spring должен найти сеанс веб-сокета. Тем не менее, я хотел бы заставить цепочку безопасности распознать, не назначен ли входящий запрос принципалу, чтобы заставить запрос вернуться через мой PreAuthFilter и восстановить сеанс.
Это возможно?
Вот краткое изложение моего метода настройки в моем файле конфигурации безопасности:
@Override
protected void configure(HttpSecurity http) throws Exception {
// Create authentication providers and authentication manager
List<AuthenticationProvider> authenticationProviders = new ArrayList<>(1);
AuthenticationProvider authProvider = preAuthenticatedAuthenticationProvider();
authenticationProviders.add(authProvider);
AuthenticationManager authenticationManager = authenticationManager(authenticationProviders);
// Create the pre-authentication filter
MyPreAuthFilter myPreAuthFilter = myPreAuthFilter(authenticationManager);
myPreAuthFilter.setAuthenticationManager(authenticationManager);
// configure http security
http
.csrf().disable()
.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
.and()
.authenticationProvider(authProvider)
.addFilter(myPreAuthFilter)
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/stomp/**").permitAll()
.antMatchers("/**").permitAll();
}
ОБНОВЛЕНИЕ: Итак, я только что узнал об этом методе на объекте http:
.anonymous().disable()
Однако, когда я использую это, все мои запросы CORS снова терпят неудачу. Я думаю, что проблема именно в предварительных запросах OPTIONS. Это не может быть аутентифицировано — оно должно быть анонимно доступно. Поэтому я думаю, что для получения нужного поведения от моей междоменной аутентификации мне нужно отключить анонимный фильтр, но это нарушает один из ключевых аспектов возможности выполнения междоменных запросов. Фу. Кто-нибудь знает, как отключить анонимность для всех запросов, кроме OPTIONS?