Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

...

Tabla de contenidos

Tabla de contenidos
outlinetrue

CONFIGURACIÓN

COMÚN

Esta configuración debe realizarse siempre, independientemente del tipo de configuración que se vaya a realizar.

Añadir en el pom.xml la siguiente dependencia:

Info

Con la configuración actual de las APIs, con el parent fundewebjs-api-parent (ver Creación y estructura de proyecto SpringBootMigración de APIs a Parent FundeWebJS),

no es necesario realizar ninguna configuración de librerías en pom.xml.

Expandir
titleVer configuración antigua.
Bloque de código
languagexml
	<dependency>
		<groupId>es.um.atica.fundewebjs.fundewebjs-api</groupId>
		<artifactId>fundewebjs-security</artifactId>
		<version>${fdwjs.version}</version>
	</dependency>
Info

La librería se encuentra a partir de la versión fdwjs 1.0.7-SNAPSHOT.

Clase Configuration (SecurityConfig)


Clase Configuration (SecurityConfig)

  1. Si no existe en nuestro proyecto, crear una clase SecurityConfig.java nueva a partir del código de FundeWebJSSecurityConfig (ubicada en la librería fundewebjs-security).

    Bloque de código
    languagejava
    collapsetrue
    @Log4j2
    @Configuration
    public class FundeWebJSSecurityConfig {
    
    	@Value( "${server.scopes}" )
    	private String[] serverScopes;
    
    	@Value( "${app.server.path}" )
    	private String apiPath;
    
    
    	/**
    	 * Proveedor de gestion de acceoss
    	 */
    	@Bean( name = "fundeWebJsDefaultSecurityFilterChain" )
    	@ConditionalOnExpression( "${fdwjs.starter.security.enable:true}" )
    	public SecurityFilterChain filterChain( HttpSecurity http ) throws Exception {
    
    		log.debug( "Carga SecurityFilterChain desde FundewebJs-Starter" );
    
    		http.requestMatchers().antMatchers( "/public/**" ).and().requestMatchers().antMatchers( apiPath + "/**" ).and()
    		.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS )
    		// configuro politica de sesion sin estado
    		.and().cors() // Aniado configuracion CORS por defecto
    		.and().csrf().disable().authorizeRequests().mvcMatchers( apiPath + "/public/**" ).permitAll()
    		.mvcMatchers( apiPath + "/**" ).hasAnyAuthority( serverScopes ).anyRequest().authenticated().and()
    		.addFilterAfter( new FundeWebJSLoggingAuthorizationFilter(), BearerTokenAuthenticationFilter.class )
    		.oauth2ResourceServer()
    		.jwt();
    
    		return http.build();
    	}
    
    }
    Si no existe en nuestro proyecto, crear una clase SecurityConfig.java nueva a partir del código de FundeWebJSSecurityConfig (ubicada en la librería fundewebjs-security).



  2. En el application.properties (de local y de los entornos en Helm Chart), añadir la siguiente property:

...

Configuración para establecer el mismo nivel LoA mínimo en todos los endpoints de una API:

  1. En la clase con la configuración de seguridad (ver pasos 1 y 2 de la configuración común), añadir el siguiente Bean para configurar el filtro para LoA, estableciendo el nivel mínimo que se desea establecer en toda nuestra API:

    Bloque de código
        @Bean
    	public UmuJwtLoaAuthenticationFilter loaFilterBean() {
    		return new UmuJwtLoaAuthenticationFilter( UmuJwtLoaLevelEnum.SUBSTANTIAL);
    	}



  2. En la misma clase, en el método configure, añadir el filtro configurado en el paso anterior de la siguiente forma:

    Bloque de código
    languagejava
    .addFilterAfter( loaFilterBean(), BearerTokenAuthenticationFilter.class )

    Hay que añadirlo justo antes de  .oauth2ResourceServer().jwt().
    Por ejemplo:

    Bloque de código
    languagejava
       @Override    
       public SecurityFilterChain filterChain( HttpSecurity http ) throws Exception {         
            http.authorizeRequests()
                .mvcMatchers("/actuator/**").permitAll()
                .mvcMatchers("/api-docs").permitAll()
                .mvcMatchers(apiPath+"/public/**").permitAll()
                .mvcMatchers(apiPath+"/private/**").hasAnyAuthority(serverScopes)
    				.anyRequest().authenticated().and()
    				.addFilterAfter( loggingFilterBean(), BearerTokenAuthenticationFilter.class )
    				.addFilterAfter( loaFilterBean(), BearerTokenAuthenticationFilter.class )
                .oauth2ResourceServer().jwt();        
           return http.build();
        }


    Advertencia

    Repetimos: ESTA CONFIGURACIÓN GLOBAL VALIDARÁ EL CLAIM EN TODOS LOS ENDPOINTS DEL API.



POR MÉTODO

Configuración para establecer niveles LoA mínimos (o diferentes) en un/os endpoints concretos de nuestra API:

...

  1. En la clase con la configuración de seguridad (ver pasos 1 y 2 de la configuración común), añadir la siguiente anotación en la declaración de la clase:

    Bloque de código
    languagejava
    @EnableGlobalMethodSecurity( prePostEnabled = true )


  2. Añadir el siguiente Bean:

    Bloque de código
    languagejava
    @Bean
    UmuJwtLoaAccessDeniedHandler accessDeniedHandler() {
       return new UmuJwtLoaAccessDeniedHandler();
    }


  3. En la misma clase, en el método configure, añadir el accessDeniedHandler configurado en el paso anterior de la siguiente forma:

    Bloque de código
    languagejava
    .and().exceptionHandling().accessDeniedHandler( accessDeniedHandler() )

    Ejemplo de configuración completa:

    Bloque de código
    languagejava
    public SecurityFilterChain filterChain( HttpSecurity http ) throws Exception {
            http
                .authorizeRequests()
                .mvcMatchers("/actuator/**").permitAll()
                .mvcMatchers("/api-docs").permitAll()
                .mvcMatchers(apiPath+"/public/**").permitAll()
                .mvcMatchers(apiPath+"/private/**").hasAnyAuthority(serverScopes)
    			.anyRequest().authenticated()
    			.and().exceptionHandling().accessDeniedHandler( accessDeniedHandler() )
    			.and().addFilterAfter( loggingFilterBean(), BearerTokenAuthenticationFilter.class )
                .oauth2ResourceServer().jwt();        
    	return http.build();     
    }


    RestController
    Ahora, en nuestro RestController, anotar el método con nuestro endpoint a securizar con la siguiente anotación:

    Bloque de código
    languagejava
    @PreAuthorize( "@umuJwtLoaAuthenticator.isSubstantialLoA(authentication)" )


    Advertencia

    El método isSubstantialLoA del componente umuJwtLoaAuthenticator establece el nivel mínimo de LoA para acceder al endpoint a medio (Substantial del eIDAS).

    Para establecer el nivel alto (High), es necesario utilizar el método isHighLoA(authentication).


    Por ejemplo:

    Bloque de código
    languagejava
        @GetMapping( "/private/afiliacion" )
    	@Operation( summary = "Endpoint test /afiliacion",
    				description = "Obtiene el dto de afiliación del token llamando a serviciosgente internamente",
    				tags = {"Serviciosgente"},
    				security = {@SecurityRequirement( name = "OIDC", scopes = "openid" )},
    				responses = {
    						@ApiResponse( responseCode = "401", description = "Token inválido o LoA mínimo no alcanzado", content = @Content ),
    						@ApiResponse( responseCode = "500", description = "Error de comunicación con serviciosgente", content = @Content ),
    						@ApiResponse( responseCode = "200", description = "Token subject.Datos de Afiliación del propietario del token obtenidos correctamente",	content = @Content( schema = @Schema( implementation = AfiliacionDTO.class ) ) )
    				} )
    	@PreAuthorize( "@umuJwtLoaAuthenticator.isSubstantialLoA(authentication)" )
    	public ResponseEntity<AfiliacionDTO> getAfiliacionGente( @AuthenticationPrincipal Jwt jwt ) {
    
    


...