Sé que asegurar la API REST es un tema muy comentado, pero no puedo crear un pequeño prototipo que cumpla con mis criterios (y necesito confirmar que estos criterios son realistas). Hay tantas opciones sobre cómo asegurar los recursos y cómo trabajar con Spring Security, necesito aclarar si mis necesidades son realistas.
Mis requisitos
- Autenticador basado en token: los usuarios proporcionarán sus credenciales y obtendrán un token de acceso único y por tiempo limitado. Me gustaría administrar la creación de tokens, verificar la validez y el vencimiento en mi propia implementación.
- Algunos recursos REST serán públicos, no es necesario autenticarse en absoluto,
- Algunos recursos serán accesibles solo para usuarios con derechos de administrador,
- Se podrá acceder a otro recurso después de la autorización para todos los usuarios.
- No quiero usar la autenticación básica
- Configuración de código Java (no XML)
Estado actual
Mi API REST funciona muy bien, pero ahora necesito protegerla. Cuando buscaba una solución, creé un javax.servlet.Filter
filtro:
@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);
}
Pero esta solución javax.servlet.filters
no funciona como necesito porque hay un problema con el manejo de excepciones a través @ControllerAdvice
de Spring servlet dispatcher
.
Lo que necesito
Me gustaría saber si estos criterios son realistas y obtener ayuda, cómo comenzar a proteger la API REST con Spring Security. Leí muchos tutoriales (por ejemplo, Spring Data REST + Spring Security ) pero todos funcionan en una configuración muy básica: los usuarios con sus credenciales se almacenan en la memoria en la configuración y necesito trabajar con DBMS y crear un autenticador propio.
Por favor, dame algunas ideas sobre cómo empezar.
fuente
Spring Security también es muy útil para proporcionar autenticación y autorización a las URL REST. No necesitamos especificar implementaciones personalizadas.
Primero, debe especificar el punto de entrada ref para restAuthenticationEntryPoint en su configuración de seguridad como se muestra a continuación.
<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>
La implementación para restAuthenticationEntryPoint podría ser la siguiente.
@Component public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException ) throws IOException { response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" ); } }
Después de esto, debe especificar RequestHeaderAuthenticationFilter. Contiene la clave RequestHeader. Esto se utiliza básicamente para identificar la autenticación del usuario. Generalmente RequestHeader lleva esta información al realizar las llamadas REST. Por ejemplo, considere el siguiente código
<bean id="preAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter"> <property name="principalRequestHeader" value="Authorization"/> <property name="authenticationManager" ref="authenticationManager" /> </bean>
Aquí,
<property name="principalRequestHeader" value="Authorization"/>
"Autorización" es la clave que presenta la solicitud entrante. Contiene la información de autenticación del usuario requerida. También debe configurar PreAuthenticatedAuthenticationProvider para cumplir con nuestro requisito.
<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>
Este código funcionará para proteger las URL REST mediante autenticación y autorización sin implementaciones personalizadas.
Para obtener el código completo, busque el siguiente enlace:
https://github.com/srinivas1918/spring-rest-security
fuente
También busqué todo este tiempo. Estoy trabajando en un proyecto similar. Descubrí que Spring tiene un módulo para implementar la sesión a través de redis. Parece fácil y útil. Yo también lo agregaré a mi proyecto. Puede ser útil:
http://docs.spring.io/spring-session/docs/1.2.1.BUILD-SNAPSHOT/reference/html5/guides/rest.html
fuente
Para validar la API REST hay 2 formas
1 - Autenticación básica con nombre de usuario y contraseña predeterminados configurados en el archivo application.properties
Autenticación básica
2 - Autenticar usando la base de datos (userDetailsService) con el nombre de usuario y la contraseña reales
Autenticación avanzada
fuente