...
| Bloque de código | ||
|---|---|---|
| ||
package es.um.atica.----.cas.config; import static es.um.atica.----.Constants.SESSION_TOKEN_HEADER; import static es.um.atica.----.Constants.LOCAL_ENV; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.jasig.cas.client.session.SingleSignOutFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.cas.ServiceProperties; import org.springframework.security.cas.authentication.CasAuthenticationProvider; import org.springframework.security.cas.web.CasAuthenticationFilter; import org.springframework.security.cas.web.authentication.ServiceAuthenticationDetails; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import es.um.atica.----.cas.handlers.CustomizedLogoutHandler; import es.um.atica.----.cas.handlers.CustomizedUrlAuthenticationSuccessHandler; @EnableWebSecurity @EnableGlobalMethodSecurity( securedEnabled = true ) public class SecurityConfigConfiguracionSeguridad extends WebSecurityConfigurerAdapter { private final AuthenticationProvider authenticationProvider; private final LogoutFilter logoutFilter; private final SingleSignOutFilter singleSignOutFilter; private final AuthenticationEntryPoint authenticationEntryPoint; private final ServiceProperties serviceProperties; @Autowired public SecurityConfigConfiguracionSeguridad ( AuthenticationEntryPoint aep, LogoutFilter lF, SingleSignOutFilter ssF, CasAuthenticationProvider casAuthenticationProvider, ServiceProperties sp ) { CasAuthenticationProvider casAuthenticationProvider, ServiceProperties sp ) { authenticationProvider = casAuthenticationProvider; logoutFilter = lF; singleSignOutFilter = ssF; authenticationEntryPoint = aep; serviceProperties = sp; } // Autenticacion básica con usuario autogenerado @Override @Override protected void configure( HttpSecurity http ) throws Exception { http.cors().and().csrf().disable().addFilter( casAuthenticationFilter( serviceProperties ) ).authorizeRequests() .regexMatchers( "^/entrada(\\/)?(\\?.+)?$" ).authenticated().and().authorizeRequests() .regexMatchers( "/public/*", "/private/*" ).permitAll().and().httpBasic() .authenticationEntryPoint( authenticationEntryPoint ).and().logout() .logoutSuccessHandler( customizedLogoutHandler() ).deleteCookies( SESSION_TOKEN_HEADER ).and() .addFilterBefore( singleSignOutFilter, CasAuthenticationFilter.class ) .addFilterBefore( logoutFilter, LogoutFilter.class ); } @Bean CorsConfigurationSource corsConfigurationSource() { final CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOriginPatterns( Arrays.asList( "*" ) ); configuration.setAllowedMethods( Arrays.asList( "*" ) ); configuration.setAllowedHeaders( Arrays.asList( "*" ) ); configuration.setAllowCredentials( true ); final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration( " source.registerCorsConfiguration( "/**", configuration ); return source; } @Bean public CustomizedLogoutHandler customizedLogoutHandler() { return new CustomizedLogoutHandler(); } @Override protected void configure( AuthenticationManagerBuilder auth ) throws Exception { auth.authenticationProvider( authenticationProvider ); } @Override protected AuthenticationManager authenticationManager() throws Exception { return new ProviderManager( Arrays.asList( authenticationProvider ) ); } @Bean AuthenticationDetailsSource<HttpServletRequest, ServiceAuthenticationDetails> dynamicServiceResolver() { return ( HttpServletRequest context ) -> { final String url = context.getRequestURL().toString(); return new ServiceAuthenticationDetails() { private static final long serialVersionUID = 1L; @Override public String getServiceUrl() { return url; } }; }; } @Bean String urlProtocol = "http:"; if ( LOCAL_ENV.equals( environment ) ) { urlProtocol = "https:"; } final String url = context.getRequestURL().toString().replace( "http:", urlProtocol ); log.error( "-- ORIGINAL Dynamic URL: " + context.getRequestURL().toString() + " ---" ); return new ServiceAuthenticationDetails() { private static final long serialVersionUID = 1L; @Override public String getServiceUrl() { log.error( "-- Dynamic URL: " + url + " ---" ); return url; } }; }; } @Bean public CasAuthenticationFilter casAuthenticationFilter( ServiceProperties sP ) throws Exception { final CasAuthenticationFilter filter = new CasAuthenticationFilter(); filter.setServiceProperties( sP ); filter.setAuthenticationManager( authenticationManager() ); filter.setFilterProcessesUrl( "/entrada/*" ); filter.setAuthenticationDetailsSource( dynamicServiceResolver() ); filter.setAuthenticationSuccessHandler( new CustomizedUrlAuthenticationSuccessHandler() ); return filter; } } |
Constantes
Se utilizan una serie de constantes que nos definimos en un archivo Constans.java situado en el paquete raíz, el mismo que la clase que inicia la aplicación, y contendrá, al menos, lo siguiente (podemos añadir constantes que nos hagan falta para otras cosas del proyecto):
...
El resto de clases se pueden descargar aquí: Clases cliente CAS.rar. Se incluyen las entidades correspondientes a base de datos, y sus correspondientes repositorios. La estructura de paquetes del proyecto, incluyendo el cliente cas, quedaría así:
...