#java #spring #spring-boot #spring-security
#java #spring #spring-boot #spring-безопасность
Вопрос:
У меня есть следующая конфигурация веб-безопасности:
@Autowired
private ApplicationAuthenticationProvider appProvider;
@Bean
@Qualifier("apiAuthenticationFilter")
public TokenAuthenticationFilter apiAuthenticationFilter(TokenAuthenticationFailureHandler failureHandler,
TokenAuthenticationSuccessHandler successHandler) throws Exception {
TokenAuthenticationFilter filter = new TokenAuthenticationFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.setAuthenticationFailureHandler(failureHandler);
filter.setAuthenticationSuccessHandler(successHandler);
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/oauth2/token", "/api/oauth2/application/token").permitAll()
.antMatchers("/api/internal**").hasAuthority("READ_ALL")
.anyRequest().authenticated()
.and()
.addFilterBefore(apiAuthenticationFilter(null, null), UsernamePasswordAuthenticationFilter.class)
.authenticationProvider(this.appProvider)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.FORBIDDEN))
.and()
.cors().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable();
}
Я попытался получить доступ http://localhost:8080/api/oauth2/token?client_id=...amp;other_query_params=param
, но вместо доступа к этой странице, как настроено здесь:
.antMatchers("/oauth2/token", "/oauth2/application/token").permitAll()
Он вызывает цепочку фильтров и фильтр, добавленный здесь:
.addFilterBefore(apiAuthenticationFilter(null, null), UsernamePasswordAuthenticationFilter.class)
который отклоняет мой запрос из-за отсутствия токена, но вместо этого он должен быть разрешен.
Это то, что говорит мой журнал:
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/oauth2/token'; against '/api/**'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /api/oauth2/token?client_id=123amp;client_secret=secretamp;code=codeamp;grant_type=authorization_code at position 1 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /api/oauth2/token?client_id=123amp;client_secret=secretamp;code=codeamp;grant_type=authorization_code at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /api/oauth2/token?client_id=123amp;client_secret=secretamp;code=codeamp;grant_type=authorization_code at position 3 of 10 in additional filter chain; firing Filter: 'HeaderWriterFilter'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /api/oauth2/token?client_id=123amp;client_secret=secretamp;code=codeamp;grant_type=authorization_code at position 4 of 10 in additional filter chain; firing Filter: 'TokenAuthenticationFilter'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/oauth2/token'; against '/api/**'
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] d.t.o.a.a.TokenAuthenticationFilter : Request is to process authentication
26-01-2021 INFO 17744 --- [nio-8080-exec-1] d.t.o.a.a.TokenAuthenticationFilter : Invoked attempAuthentication
26-01-2021 DEBUG 17744 --- [nio-8080-exec-1] d.t.o.a.a.TokenAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Invalid token submitted: null
Комментарии:
1. не
"/oauth2/token", "/oauth2/application/token"
должно быть"/api/oauth2/token", "/api/oauth2/application/token"
?2. @Lino Да, это было раньше, но тогда это тоже не работает
3. я думаю, .anyRequest().authenticated() переопределяет ваш URL PermitAll()
Ответ №1:
Хорошо, я исправил ошибку прямо сейчас, это была логическая ошибка. Я хочу объяснить, в чем была проблема.
Поскольку я хотел использовать аутентификацию oauth2 в своем приложении, я добавил фильтр, вызываемый TokenAuthenticationFilter
для получения Authorization
заголовка и аутентификации с использованием учетных данных в этом заголовке. Но мой фильтр не ограничивал случаи применения. Таким образом, все запросы, а также запросы «PermitAll», проходили через этот фильтр и отклонялись из-за отсутствия аутентификации. Поэтому я изменил свой код, чтобы фильтр применялся только в том случае, если установлен заголовок «Авторизация», и теперь все работает.