sábado, 13 de agosto de 2016

Spring Boot Security: nivel básico

En este post, vamos a intentar explicar como configurar de forma básica Spring Security 4 con Spring Boot. Accediendo a los roles a través de JDBC y con los passwords encriptados. Se puede configurar en 4 sencillas clases y tenéis todo el código aquí (ExampleSpringSecurity) (en src/test/resources teneis incluidos los scripts BBDD).

1. Application: Esta clase tendrá la anotación 'SpringBootApplication'  y un método main que nos permitirá arrancar la aplicación.
2. MvcConfig: En esta clase tendremos la configuración para la navegación url-pantallas/vistas. Y también indicaremos a través de 'viewResolver' como resolver las  el viewResolver, que nos permitirá indicar la pantalla/vista.


@Override
public void addViewControllers(final ViewControllerRegistry registry) {
 registry.addViewController("/home").setViewName("home");
 registry.addViewController("/").setViewName("home");
 registry.addViewController("/hello").setViewName("hello");
 registry.addViewController("/login").setViewName("login");
 registry.addViewController("/403").setViewName("403");
}
@Bean
public InternalResourceViewResolver viewResolver() {
 InternalResourceViewResolver resolver = new InternalResourceViewResolver();
 resolver.setPrefix("/WEB-INF/jsp/");
 resolver.setSuffix(".jsp");
 return resolver;
}

En el código podemos ver que si indicamos una vista denominada 'hello', buscará y redireccionará a la pantalla /WEB-INF/jsp/hello.jsp'.

3. AuthenticationProviderConfig: En esta clase declararemos el 'dataSource' que nos permitirá conectarnos a la BBDD. Y lo mas importante el bean 'userDetailService', en el cual implementaremos como obtener el usuario y contraseña almacenados en BBDD y como obtener los roles asociados al usuario.

@Bean(name = "userDetailsService")
public UserDetailsService userDetailsService() {
 JdbcDaoImpl jdbcImpl = new JdbcDaoImpl();
 jdbcImpl.setDataSource(dataSource());
 String usersByUserNameQuery = "select username,password, enabled from users where username=?";
 String authoritiesByUsernameQuery = "select u.username, ur.authority from user_roles ur, users u where username=? and u.user_id = ur.user_id";
 jdbcImpl.setUsersByUsernameQuery(usersByUserNameQuery);
 jdbcImpl.setAuthoritiesByUsernameQuery(authoritiesByUsernameQuery);
 return jdbcImpl;
}

4. WebSecurityConfig: En esta clase realizaremos la configuración propia de Spring Security, en el aspecto de que indicamos como se va a realizar la obtención de los datos (a través de userDetailsService). Como vamos a realizar la encriptación de la contraseña (a través de una clase incluida dentro de Spring como es: BCryptPasswordEncoder). Y por último configurar todas las urls de acceso de la aplicación e indicar si son accesible por todos los usuarios, si solo son accesible por un determinado rol y configuraciones normales como cuales son las paginas de login y logout.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 @Autowired
 UserDetailsService userDetailsService;
 @Bean(name = "passwordEncoder")
 public PasswordEncoder passwordencoder() {
  return new BCryptPasswordEncoder();
 }
 @Autowired
 public void configAuthentication(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
 }
 @Override
 protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/hello").access("hasRole('ROLE_ADMIN')").anyRequest()
    .permitAll()
    .and().formLogin().loginPage("/login").usernameParameter("username")
    .passwordParameter("password")
    .and().logout().logoutSuccessUrl("/login?logout")
    .and().exceptionHandling().accessDeniedPage("/403")
    .and().csrf();
 }
}

Toda la configuración se puede crear en un único fichero sin problemas. Pero la idea de realizarlo así es aumentar la claridad en la configuración de la aplicación.

Este ejemplo lo he sacado de esta Web, donde además podemos ver un post algo más complejo con JPA Data.

No hay comentarios:

Publicar un comentario