Аутентификация при каждом вызове API - PullRequest
0 голосов
/ 24 июня 2019

В настоящее время у меня есть сервис Spring, который проходит аутентификацию через страницу входа.Теперь желательно иметь способ аутентификации пользователя для каждого запроса API с использованием сертификата клиента и закрытого ключа.Я создал POST-запрос к внешней конечной точке, которую я использую для аутентификации пользователя.Мне удалось аутентифицировать пользователя в фильтре аутентификации, но затем он отображает ошибку 405.

public class AuthenticationFilter extends GenericFilterBean {

    private AuthenticationManager authenticationManager;

    public AuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest http_request = (HttpServletRequest) request;
        HttpServletResponse http_response = (HttpServletResponse) response;

        String cert_filename = "certificate.pem";
        File cert_file = new File(cert_filename);

        if(cert_file.createNewFile())
            System.out.println("Successfully created private cert file");
        else
            System.out.println("Cert file could not be created");

        BufferedWriter cert_writer = new BufferedWriter(new FileWriter(cert_filename));
        cert_writer.write(cert);
        cert_writer.close();

        String key_filename = "private_key.key";
        File key_file = new File(key_filename);

        if(key_file.createNewFile())
            System.out.println("Successfully created private key file");
        else
            System.out.println("Key file could not be created");

        BufferedWriter key_writer = new BufferedWriter(new FileWriter(key_filename));
        key_writer.write(key);
        key_writer.close();

        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.redirectErrorStream(true);
        processBuilder.command("curl", ..., ...);
        Process process = processBuilder.start();
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String line;
        while ( (line = reader.readLine()) != null) {
            builder.append(line);
            builder.append(System.getProperty("line.separator"));
        }
        String result = builder.toString();

        System.out.println(result);
        if(result.contains("\"successful\": true")) {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
            Authentication auth = authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
//            TokenResponse tokenResponse = new TokenResponse(auth.getDetails().toString());
//            String tokenJsonResponse = new ObjectMapper().writeValueAsString(tokenResponse);
            http_response.setStatus(HttpServletResponse.SC_OK);
            //http_response.sendError(HttpServletResponse.SC_OK);
//            http_response.addHeader("Content-Type", "application/json");
//            http_response.getWriter().print(tokenJsonResponse);
            chain.doFilter(request, response);
        }
        else{
            http_response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            http_response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }

    }
}


@EnableWebSecurity
@Order(1000)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    String[] permitted  =  {
            "/login",
            ...
    };

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("{noop}password")
                .roles("USER");

    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint)
                .and()
                .authorizeRequests()
                .antMatchers(permitted).permitAll()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
                .loginPage("/login")
                .defaultSuccessUrl("/swagger-ui.html", true)
                .and()
                .logout()
                .clearAuthentication(true)
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login").permitAll()
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true);
        http.addFilterAfter(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
    }


}

1 Ответ

1 голос
/ 25 июня 2019

Теперь необходимо иметь способ аутентификации пользователя для каждого запроса API с использованием сертификата клиента и закрытого ключа

Видимо, вам не хватает некоторых очень простых принципов, как работает аутентификация клиента через ssl. Идея состоит в том, что клиент имеет свою пару ключей (частный и открытый ключ) и сертификат, который должен быть подписан доверенным центром сертификации .

Для целей тестирования вы можете использовать самозаверяющий сертификат, просто ему нужно доверять (в хранилище доверенных сертификатов), см. Ссылку на блог ниже.

Аутентификация будет проходить на уровне канала (https), а информация о клиенте (сертификат dn, ..) передается механизмом в качестве заголовков или контекста запроса

Вы можете заглянуть в следующий блог: Аутентификация X.509 в Spring Security

Обычно я бы скопировал соответствующую информацию из внешнего ресурса в ответ, но в этом случае я бы скопировал весь пост.

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