Как защитить 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 Безопасность ) но все работают в очень простой конфигурации-пользователи с их учетные данные хранятся в памяти в конфигурации и мне нужно работать с СУБД и создавать собственный Аутентификатор.
Пожалуйста, дайте мне несколько идей, как начать.
4 ответов:
Аутентификация на основе токенов-пользователи предоставят свои учетные данные и получат уникальный и ограниченный по времени маркер доступа. Я хотел бы управлять токеном создание, проверка валидности, экспирация в моей собственной реализации.
На самом деле, используйте фильтр для токена Auth-лучший способ в этом случае
В конечном счете, вы можете создать CRUD с помощью данных Spring для управления свойствами токена, такими как срок действия и т. д.
Вот мой жетон. фильтр: http://pastebin.com/13WWpLq2
И Реализация Службы Токенов
Некоторые ресурсы 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-адреса с помощью аутентификации и авторизации без каких-либо пользовательских реализаций.
Для полного кода, пожалуйста, найдите ссылку ниже:
Я искал и это долгое время.Я работаю над подобным проектом.Я узнал, что у 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