Как защитить REST API с помощью Spring Boot и Spring Security?
Я знаю, что защита REST API-это широко обсуждаемая тема, но я не могу создать небольшой прототип, который соответствует моим критериям (и мне нужно подтвердить, что эти критерии реалистичны). Есть так много вариантов, как защитить ресурсы и как работать с Spring security, мне нужно уточнить, реалистичны ли мои потребности.
мои требования
- Аутентификатор на основе токенов-пользователи будут предоставлять свои учетные данные и получать уникальные и ограниченные по времени маркер доступа. Я хотел бы управлять созданием токенов, проверкой действительности, истечением срока действия в моей собственной реализации.
- некоторые остальные ресурсы будут открытыми - нет необходимости для проверки подлинности на всем,
- некоторые ресурсы будут доступны только для пользователей с правами администратора,
- другие ресурсы будут доступны после авторизации для всех пользователей.
- я не хочу использовать обычную проверку подлинности
- конфигурация кода Java (нет XML)
текущее состояние
мой REST 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
С весны servlet dispatcher
.
что мне нужно
Я хотел бы знать, если эти критерии реалистичны и получить любой справка, как начать защиту REST API с помощью Spring Security. Я читал много учебников (например,Spring Data REST + Spring Security), но все работы в очень простой конфигурации - пользователи с учетные данные хранятся в в конфигурации и мне нужно работать с СУБД и создать собственный Аутентификатор.
пожалуйста, дайте мне несколько идей, как начать.
4 ответа:
аутентификация на основе токенов-пользователи будут предоставлять свои учетные данные и получать уникальный и ограниченный по времени токен доступа. Я хотел бы управлять токеном создание, проверка валидности, экспирации в моей собственной реализации.
На самом деле, используйте фильтр для токена Auth - лучший способ в этом случае
в конце концов, вы можете создать CRUD через Spring Data для управления свойствами токена, такими как срок действия и т. д.
вот мой жетон фильтр: http://pastebin.com/13WWpLq2
И Реализация Службы Токенов
некоторые остальные ресурсы будут открытыми - нет необходимости для проверки подлинности на все
это не проблема, вы можете управлять своими ресурсами через 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 {}
вы должны переопределить настроить метод. Код ниже, например, как настроить сопоставители. Это из другого проекта.
@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