POST oauth-токен первоначально отправляет запрос OPTIONS без данных / заголовков и завершается с 401 - PullRequest
0 голосов
/ 12 апреля 2020

У меня проблема с извлечением жетона oauth из бэкэнда загрузочной пружины из реактора ax ios с использованием:

async login() {
const tokenurl = 'http://localhost:8080/oauth/token';
const data = {
  grant_type: 'password',
  username: this.state.email,
  password: this.state.password,
  scope: 'write'
};
var headers = {
  headers: {'Authorization' : 'Basic ' + btoa('client:secret') ,
  'Content-Type': 'application/x-www-form-urlencoded'}
}
axios.post(tokenurl,data,headers)

отправляется первый запрос OPTION без заголовков / данных, а 401 не выполняется.

Access is denied (user is anonymous)
org.springframework.security.access.AccessDeniedException: Access is denied. 

Это запрос, который я получил в своем бэкэнде, заголовок / данные удалены.

[OPTIONS /oauth/token HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization
Referer: http://localhost:3000/signin/
Origin: http://localhost:3000
Connection: keep-alive

Опция запроса / почтовый токен успешно работает как в curl, так и в Postman с новым токеном доступа.

curl -X POST -u "client:secret" -d "grant_type=password&username=tata@tata.com&password=test&scope=write" -H "origin:http://localhost:3000" -H "Access-Control-Request-Headers:authorization" http://localhost:8080/oauth/token

curl -X OPTIONS -u "client:secret" -d "grant_type=password&username=tata@tata.com&password=test&scope=write" -H "origin:http://localhost:3000" -H "Access-Control-Request-Headers:authorization" http://localhost:8080/oauth/token

Я заметил, что удаление -u "client: secret" в запросе curl OPTIONS приводит к той же ошибке, что и ax ios.

Безопасность Spring Boot Backend и конфигурация oauth2.0:

WebSecurityConfig:

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.cors().configurationSource(corsConfigurationSource()).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().httpBasic().realmName(securityRealm).and().csrf().disable();
    }

    @Bean(name="CorsSource")
    public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.applyPermitDefaultValues();    configuration.addAllowedMethod(HttpMethod.OPTIONS);
    configuration.addAllowedOrigin("http://localhost:3000");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
    }
}

RessourceConfig:

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers(HttpMethod.POST,"/api/**").hasRole("PROVIDER").antMatchers(HttpMethod.GET, "/api/**").hasRole("CLIENT").antMatchers("/admin/**").hasRole("ADMIN");
    }
}

AuthorizationServerConfig

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer.inMemory().withClient(clientId).secret(passwordEncoder.encode(clientSecret)).authorizedGrantTypes(grantType).scopes(scopeRead,scopeWrite).resourceIds(esourceIds); //ressourceIds:api,admin
    }
}

У вас есть идеи, как я могу решить эту проблему?

спасибо:)

1 Ответ

0 голосов
/ 18 апреля 2020

после долгих поисков я мог найти обходной путь для решения моей проблемы в бэкэнде весенней загрузки, фактически с включением authorizationServer, платформа настроит разрешения для доступа к конечным точкам oauth в классе AuthorizationServerEndpointsConfiguration и не внесет в белый список Метод OPTION, см. https://github.com/spring-projects/spring-security-oauth/issues/330

для решения проблемы 401: 1. в конфигурации безопасности весной я добавил:

// ignore spring security preflight request for oauth (OPTIONS)
    @Override
    public void configure(WebSecurity web) throws Exception {
        // TODO Auto-generated method stub
         web.ignoring().antMatchers(HttpMethod.OPTIONS, "/oauth/**");
}

и добавил фильтр cors, который вернет OK по умолчанию, если метод OPTIONS. (чтобы избежать любого конфликта, я удалил использование CorsConfigurationSource и http.cors () в ScurityConfig, см. реализацию в моем вопросе). Фильтр упорядочен как HIGHEST_PRECEDENCE, и он должен выполняться первым для каждого запроса.

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter("/*")
public class CorsFilter implements Filter {

    public CorsFilter() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) res;
        final HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

этот обходной путь исправляет мою проблему, но это не идеальное решение, я буду очень рад получить другие решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...