spring-security - mvc - spring security tutorial español pdf
¿Cómo hacer que Spring Security acepte JSON en lugar de parámetros de formulario? (1)
Estoy intentando cambiar JHipster para que use un objeto JSON para autenticación en lugar de parámetros de formulario. Logré hacer que esto funcione para su mecanismo de autenticación JWT. Ahora me gustaría hacerlo para otras opciones de autenticación.
¿Hay alguna manera fácil de cambiar la configuración de seguridad predeterminada de Spring Security para permitir esto? Esto es lo que JHipster usa ahora:
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.rememberMeParameter("remember-me")
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
Me gustaría enviar lo siguiente como JSON en lugar de los parámetros del formulario:
{username: "admin", password: "admin", rememberMe: true}
He hecho tal tipo de cosas. La solución no es difícil, pero hice el truco creando un filtro de seguridad personalizado basado principalmente en UserNamePasswordAuthenticationFilter.
En realidad, debes anular el método de AtteAuthentication . Solo anula getPassword y obtainUnombre de usuario puede no ser posible, ya que desea leer el cuerpo de la solicitud y debe hacerlo de una vez para ambos parámetros (si no crea un tipo de envoltorio HttpServletRequest de varias lecturas)
La solución debe ser así:
public class JsonUserNameAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
//[...]
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
UsernamePasswordAuthenticationToken authRequest =
this.getUserNamePasswordAuthenticationToken(request);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
//[...]
protected UserNamePasswordAuthenticationToken(HttpServletRequest request){
// here read the request body and retrieve the params to create a UserNamePasswordAuthenticationToken. You may use jackson of whatever you like most
}
//[...]
}
Entonces debes configurarlo. Siempre uso la configuración basada en xml para este tipo de configuraciones complejas,
<beans:bean id="jsonUserNamePasswordAuthenticationFilter"
class="xxx.yyy.JsonUserNamePasswordAuthenticationFilter">
<beans:property name="authenticationFailureHandler>
<beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<!-- set the failure url to a controller request mapping returning failure response body.
it must be NOT secured -->
</beans:bean>
</beans:property>
<beans:property name="authenticationManager" ref="mainAuthenticationManager" />
<beans:property name="authenticationSuccessHandler" >
<beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<!-- set the success url to a controller request mapping returning success response body.
it must be secured -->
</beans:bean>
</beans:property>
</beans:bean>
<security:authentication-manager id="mainAuthenticationManager">
<security:authentication-provider ref="yourProvider" />
</security:authentication-manager>
<security:http pattern="/login-error" security="none"/>
<security:http pattern="/logout" security="none"/>
<security:http pattern="/secured-pattern/**" auto-config=''false'' use-expressions="false"
authentication-manager-ref="mainAuthenticationManager"
create-session="never" entry-point-ref="serviceAccessDeniedHandler">
<security:intercept-url pattern="/secured-pattern/**" access="ROLE_REQUIRED" />
<security:custom-filter ref="jsonUserNamePasswordAuthenticationFilter"
position="FORM_LOGIN_FILTER" />
<security:access-denied-handler ref="serviceAccessDeniedHandler"/>
<security:csrf disabled="true"/>
</security:http>
Puede crear algunos objetos adicionales como access-denied-handler, pero esa es la parte más fácil de la cosa