tutorial example ejemplo java spring spring-security

java - example - spring security module



Filtro de autenticación personalizada de Spring Security utilizando Java Config (1)

Resolví mi problema al verificar el estado de autenticación en el filtro antes de activar el proveedor de autenticación ....

Config

.and() .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) .authenticationProvider(tokenAuthenticationProvider) .exceptionHandling().authenticationEntryPoint(tokenEntryPoint)

Filtrar

@Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { logger.debug(this + "received authentication request from " + request.getRemoteHost() + " to " + request.getLocalName()); if (request instanceof HttpServletRequest) { if (isAuthenticationRequired()) { // extract token from header OEWebToken token = extractToken(request); // dump token into security context (for authentication-provider to pick up) SecurityContextHolder.getContext().setAuthentication(token); } else { logger.debug("session already contained valid Authentication - not checking again"); } } chain.doFilter(request, response); } private boolean isAuthenticationRequired() { // apparently filters have to check this themselves. So make sure they have a proper AuthenticatedAccount in their session. Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); if ((existingAuth == null) || !existingAuth.isAuthenticated()) { return true; } if (!(existingAuth instanceof AuthenticatedAccount)) { return true; } // current session already authenticated return false; }

Estoy intentando configurar Spring Security utilizando la configuración de Java en una aplicación web básica para autenticar contra un servicio web externo usando un token cifrado provisto en un parámetro de solicitud de URL.

Me gustaría (creo) tener un filtro de seguridad que intercepte las solicitudes del Portal de inicio de sesión (todas van a / autenticar), el filtro usará un AuthenticationProvider para procesar la lógica empresarial del proceso de autenticación.

Portal de inicio de sesión -> Redirigir ''/ authenticar'' (+ Token) -> Autenticar Token de nuevo al Portal de inicio de sesión (WS) -> Si tiene éxito, obtenga roles y configure al usuario.

He creado un filtro ...

@Component public final class OEWebTokenFilter extends GenericFilterBean { @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { OEToken token = extractToken(request); // dump token into security context (for authentication-provider to pick up) SecurityContextHolder.getContext().setAuthentication(token); } } chain.doFilter(request, response); }

Un AuthenticationProvider ...

@Component public final class OEWebTokenAuthenticationProvider implements AuthenticationProvider { @Autowired private WebTokenService webTokenService; @Override public boolean supports(final Class<?> authentication) { return OEWebToken.class.isAssignableFrom(authentication); } @Override public Authentication authenticate(final Authentication authentication) { if (!(authentication instanceof OEWebToken)) { throw new AuthenticationServiceException("expecting a OEWebToken, got " + authentication); } try { // validate token locally OEWebToken token = (OEWebToken) authentication; checkAccessToken(token); // validate token remotely webTokenService.validateToken(token); // obtain user info from the token User userFromToken = webTokenService.obtainUserInfo(token); // obtain the user from the db User userFromDB = userDao.findByUserName(userFromToken.getUsername()); // validate the user status checkUserStatus(userFromDB); // update ncss db with values from OE updateUserInDb(userFromToken, userFromDB); // determine access rights List<GrantedAuthority> roles = determineRoles(userFromDB); // put account into security context (for controllers to use) return new AuthenticatedAccount(userFromDB, roles); } catch (AuthenticationException e) { throw e; } catch (Exception e) { // stop non-AuthenticationExceptions. otherwise full stacktraces returned to the requester throw new AuthenticationServiceException("Internal error occurred"); } }

Y mi Spring Security Config

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired OESettings oeSettings; @Bean(name="oeAuthenticationService") public AuthenticationService oeAuthenticationService() throws AuthenticationServiceException { return new AuthenticationServiceImpl(new OEAuthenticationServiceImpl(), oeSettings.getAuthenticateUrl(), oeSettings.getApplicationKey()); } @Autowired private OEWebTokenFilter tokenFilter; @Autowired private OEWebTokenAuthenticationProvider tokenAuthenticationProvider; @Autowired private OEWebTokenEntryPoint tokenEntryPoint; @Bean(name="authenticationManager") @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(tokenAuthenticationProvider); } @Bean public FilterRegistrationBean filterRegistrationBean () { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(tokenFilter); registrationBean.setEnabled(false); return registrationBean; } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/authenticate**").permitAll() .antMatchers("/resources/**").hasAuthority("ROLE_USER") .antMatchers("/home**").hasAuthority("ROLE_USER") .antMatchers("/personSearch**").hasAuthority("ROLE_ADMIN") // Spring Boot actuator endpoints .antMatchers("/autoconfig**").hasAuthority("ROLE_ADMIN") .antMatchers("/beans**").hasAuthority("ROLE_ADMIN") .antMatchers("/configprops**").hasAuthority("ROLE_ADMIN") .antMatchers("/dump**").hasAuthority("ROLE_ADMIN") .antMatchers("/env**").hasAuthority("ROLE_ADMIN") .antMatchers("/health**").hasAuthority("ROLE_ADMIN") .antMatchers("/info**").hasAuthority("ROLE_ADMIN") .antMatchers("/mappings**").hasAuthority("ROLE_ADMIN") .antMatchers("/metrics**").hasAuthority("ROLE_ADMIN") .antMatchers("/trace**").hasAuthority("ROLE_ADMIN") .and() .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) .authenticationProvider(tokenAuthenticationProvider) .antMatcher("/authenticate/**") .exceptionHandling().authenticationEntryPoint(tokenEntryPoint) .and() .logout().logoutSuccessUrl(oeSettings.getUrl()); } }

Mi problema es la configuración del filtro en mi clase SpringConfig. Deseo que el filtro solo entre en vigencia cuando la solicitud es para la URL / authenticate, agregué .antMatcher ("/ authenticate / **") a la configuración del filtro.

.and() .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) .authenticationProvider(tokenAuthenticationProvider) .antMatcher("/authenticate/**") .exceptionHandling().authenticationEntryPoint(tokenEntryPoint)

Cuando tengo esta línea en todas las demás URL ya no están protegidas, puedo navegar manualmente a / home sin autenticar, eliminar la línea y / home está autenticado.

¿Debo declarar un filtro que solo se aplica a una URL específica?

¿Cómo puedo implementar esto mientras mantengo la seguridad de otras URL?