Как защитить REST API с помощью Spring Boot и Spring Security?



Я знаю, что защита REST API-это широко обсуждаемая тема, но я не могу создать небольшой прототип, который соответствует моим критериям (и мне нужно подтвердить, что эти критерии реалистичны). Существует так много вариантов, как обезопасить ресурсы и как работать с Spring security, мне нужно уточнить, реалистичны ли мои потребности.



Мои требования




  • Аутентификатор на основе токенов-пользователи будут предоставлять свои учетные данные и получать уникальный и ограниченный по времени токен доступа. Я бы нравится управлять созданием токенов, проверкой валидности, истечения срока действия в моей собственной реализации.

  • некоторые ресурсы REST будут общедоступными - аутентификация вообще не требуется,

  • некоторые ресурсы будут доступны только пользователям с правами администратора,

  • другой ресурс будет доступен после авторизации для всех пользователей.

  • я не хочу использовать обычную аутентификацию

  • конфигурация кода Java (не XML)


Текущее состояние



Мой отдых API работает очень хорошо, но теперь мне нужно его обезопасить. Когда я искал решение, я создал фильтр javax.servlet.Filter:



  @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
Account account = accountDao.find(accessToken);

if (account == null) {
throw new UnauthorizedException();
}

chain.doFilter(req, res);

}


Но это решение с javax.servlet.filters не работает так, как мне нужно, потому что есть проблема с обработкой исключений через @ControllerAdvice с Spring servlet dispatcher.



Что мне нужно



Я хотел бы знать, реалистичны ли эти критерии, и получить любую помощь, как начать защищать REST API с Spring Security. Я читал много учебников (например, Spring Data REST + Spring Безопасность ) но все работают в очень простой конфигурации-пользователи с их учетные данные хранятся в памяти в конфигурации и мне нужно работать с СУБД и создавать собственный Аутентификатор.



Пожалуйста, дайте мне несколько идей, как начать.

687   4  

4 ответов:

Аутентификация на основе токенов-пользователи предоставят свои учетные данные и получат уникальный и ограниченный по времени маркер доступа. Я хотел бы управлять токеном создание, проверка валидности, экспирация в моей собственной реализации.

На самом деле, используйте фильтр для токена Auth-лучший способ в этом случае

В конечном счете, вы можете создать CRUD с помощью данных Spring для управления свойствами токена, такими как срок действия и т. д.

Вот мой жетон. фильтр: http://pastebin.com/13WWpLq2

И Реализация Службы Токенов

Http://pastebin.com/dUYM555E

Некоторые ресурсы REST будут общедоступными - аутентификация вообще не требуется

Это не проблема, вы можете управлять своими ресурсами через Spring security config следующим образом: .antMatchers("/rest/blabla/**").permitAll()

Некоторые ресурсы будут доступны только пользователям с правами администратора,

Взгляните на аннотацию к классу @Secured. Пример:

@Controller
@RequestMapping(value = "/adminservice")
@Secured("ROLE_ADMIN")
public class AdminServiceController {

Другой ресурс будет доступен после авторизации для всех пользователей.

Возвращаясь к Spring Security configure, вы можете настроить свой url следующим образом:

    http
            .authorizeRequests()
            .antMatchers("/openforall/**").permitAll()
            .antMatchers("/alsoopen/**").permitAll()
            .anyRequest().authenticated()

Я не хочу использовать обычную аутентификацию

Да, через фильтр токенов ваши пользователи будут аутентифицированы.

Конфигурация кода Java (не XML)

Возвращаясь к словам выше, посмотрите на @EnableWebSecurity. Ваш класс будет:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

У вас есть переопределить методconfigure . Код ниже, просто для примера, как настроить сопоставители. Это из другого проекта.

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/assets/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .loginPage("/login")
                .defaultSuccessUrl("/", true)
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
                .logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .and()
                .csrf();
}

Spring security также очень полезен для обеспечения аутентификации и авторизации для остальных URL-адресов. Нам не нужно указывать какие-либо пользовательские реализации.

Во-первых, необходимо указать точку входа-ref для restAuthenticationEntryPoint в конфигурации безопасности, как показано ниже.

 <security:http pattern="/api/**" entry-point-ref="restAuthenticationEntryPoint" use-expressions="true" auto-config="true" create-session="stateless" >

    <security:intercept-url pattern="/api/userList" access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/api/managerList" access="hasRole('ROLE_ADMIN')"/>
    <security:custom-filter ref="preAuthFilter" position="PRE_AUTH_FILTER"/>
</security:http>

Реализация для restAuthenticationEntryPoint может быть такой, как показано ниже.

 @Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

   public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException ) throws IOException {
      response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
   }
}

После этого необходимо указать RequestHeaderAuthenticationFilter. Он содержит ключ RequestHeader. Это в основном используется для идентификации аутентификации пользователя. Обычно RequestHeader несет эту информацию во время выполнения остальных вызовов. Например рассмотрим ниже код

   <bean id="preAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="Authorization"/>
    <property name="authenticationManager" ref="authenticationManager" />
  </bean>

Здесь,

<property name="principalRequestHeader" value="Authorization"/>

"авторизация" - это ключ, представленный входящим запросом. Он содержит необходимую аутентификационную информацию пользователя. Кроме того, вам необходимо настроить PreAuthenticatedAuthenticationProvider для выполнения наших требований.

   <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
  <bean id="userDetailsServiceWrapper"
      class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
    <property name="userDetailsService" ref="authenticationService"/>
  </bean>
</property>
</bean>

Этот код будет работать для обеспечения безопасности остальных URL-адреса с помощью аутентификации и авторизации без каких-либо пользовательских реализаций.

Для полного кода, пожалуйста, найдите ссылку ниже:

Https://github.com/srinivas1918/spring-rest-security

Я искал и это долгое время.Я работаю над подобным проектом.Я узнал, что у Spring есть модуль для реализации сеанса через redis. Это выглядит просто и полезно. Я тоже добавлю к своему проекту. Может быть полезно:

Http://docs.spring.io/spring-session/docs/1.2.1.BUILD-SNAPSHOT/reference/html5/guides/rest.html

Для проверки REST API существует 2 способа

1-базовая аутентификация с использованием имени пользователя и пароля по умолчанию, настроенных в приложении.файл свойств

Базовая Аутентификация

2 - аутентификация с использованием базы данных (userDetailsService) с фактическим именем пользователя и паролем

Расширенная Аутентификация

Comments

    Ничего не найдено.