java - authorizerequests - spring security tutorial
¿Cómo representar el "filtro personalizado" de Spring Security utilizando la configuración de Java? (3)
¿Cuál es la configuración de Java equivalente para la etiqueta Spring Security <custom-filter>
?
<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/>
</http>
Lo intenté
http.addFilter( new MyUsernamePasswordAuthenticationFilter() )
donde la clase extiende el filtro predeterminado, pero siempre emplea el formLogin
predeterminado de formLogin
.
Mi filtro
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
// proof of concept of how the http.addFilter() works
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
System.out.println("running my own version of UsernmePasswordFilter ... ");
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
La pieza de configuración relevante:
@Configuration
@EnableWebMvcSecurity // annotate class configuring AuthenticationManagerBuilder
@ComponentScan("com.kayjed")
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**","/signup").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
http.addFilter(new MyUsernamePasswordAuthenticationFilter());
}
...
}
La ejecución de la aplicación MVC en el depurador siempre muestra la autenticación de intentos de inicio de sesión del UsernamePasswordAuthenticationFilter
predeterminado en lugar de mi intención de emplear la clase MyUsernamePasswordAuthenticationFilter
.
De todos modos, no estoy tratando de hacer que alguien depure el código; más bien, me encantaría ver un buen ejemplo utilizando la configuración de Java que realiza el equivalente del elemento de filtro personalizado en el enfoque XML. La documentación es un poco escasa.
Algunas cuestiones que debe tener en cuenta:
Su filtro debe agregarse antes del nombre de
UsernamePasswordAuthenticationFilter
estándarPasswordAuthenticationFilterhttp.addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
Si extiende UsernamePasswordAuthenticationFilter, su filtro regresará inmediatamente sin hacer nada a menos que establezca un
RequestMatcher
myAuthFilter.setRequiresAuthenticationRequestMatcher( new AntPathRequestMatcher("/login","POST"));
Toda la configuración que realice en
http.formLogin().x().y().z()
se aplica alUsernamePasswordAuthenticationFilter
estándar, no al filtro personalizado que construye. Tendrá que configurarlo manualmente usted mismo. Mi inicialización del filtro de autenticación se ve así:@Bean public MyAuthenticationFilter authenticationFilter() { MyAuthenticationFilter authFilter = new MyAuthenticationFilter(); authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST")); authFilter.setAuthenticationManager(authenticationManager); authFilter.setAuthenticationSuccessHandler(new MySuccessHandler("/app")); authFilter.setAuthenticationFailureHandler(new MyFailureHandler("/login?error=1")); authFilter.setUsernameParameter("username"); authFilter.setPasswordParameter("password"); return authFilter; }
Intente agregar @Component
a su clase MyUsernamePasswordAuthenticationFilter
.
Esta anotación hace que la clase sea considerada como candidata para la detección automática, vea: @Component
Para esto:
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/>
Puedes añadir esto:
.addFilter[Before|After](authenticationTokenProcessingFilter, UsernamePasswordAuthenticationFilter.class)
No encuentro ningún problema en este código. Creo que tu configuración está bien. El problema está en otra parte. Tengo un código similar,
package com.programsji.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.programsji.security.CustomAuthenticationProvider;
import com.programsji.security.CustomSuccessHandler;
import com.programsji.security.CustomUsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**", "/theme/**").and()
.debug(true);
}
@Bean
public CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter()
throws Exception {
CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter = new CustomUsernamePasswordAuthenticationFilter();
customUsernamePasswordAuthenticationFilter
.setAuthenticationManager(authenticationManagerBean());
customUsernamePasswordAuthenticationFilter
.setAuthenticationSuccessHandler(customSuccessHandler());
return customUsernamePasswordAuthenticationFilter;
}
@Bean
public CustomSuccessHandler customSuccessHandler() {
CustomSuccessHandler customSuccessHandler = new CustomSuccessHandler();
return customSuccessHandler;
}
@Bean
public CustomAuthenticationProvider customAuthenticationProvider() {
CustomAuthenticationProvider customAuthenticationProvider = new CustomAuthenticationProvider();
return customAuthenticationProvider;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
List<AuthenticationProvider> authenticationProviderList = new ArrayList<AuthenticationProvider>();
authenticationProviderList.add(customAuthenticationProvider());
AuthenticationManager authenticationManager = new ProviderManager(
authenticationProviderList);
return authenticationManager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/reportspage").hasRole("REPORT")
.antMatchers("/rawdatapage").hasRole("RAWDATA").anyRequest()
.hasRole("USER").and().formLogin().loginPage("/login")
.failureUrl("/login?error")
.loginProcessingUrl("/j_spring_security_check")
.passwordParameter("j_password")
.usernameParameter("j_username").defaultSuccessUrl("/")
.permitAll().and().httpBasic().and().logout()
.logoutSuccessUrl("/login?logout").and().csrf().disable()
.addFilter(customUsernamePasswordAuthenticationFilter());
}
}
Está funcionando bien en mi aplicación. puede descargar este proyecto completo desde url: https://github.com/programsji/rohit/tree/master/UsernamePasswordAuthenticationFilter