...
Dependiendo de la situación, se distinguen dos tipos de configuraciones:
- Global: Todos los endpoints de nuestra API requerirán el mismo nivel LoA establecido en su configuración.
- Por endpointmétodo: Configurar el nivel LoA de forma independiente para cada endpoint.
...
Configuración para establecer niveles LoA mínimos (o diferentes) en un/os endpoints concretos de nuestra API:
Clase Configuration (SecurityConfig)
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 language java @EnableGlobalMethodSecurity( prePostEnabled = true )
Añadir el siguiente Bean:
Bloque de código language java @Bean UmuJwtLoaAccessDeniedHandler accessDeniedHandler() { return new UmuJwtLoaAccessDeniedHandler(); }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 language java .and().exceptionHandling().accessDeniedHandler( accessDeniedHandler() )
Ejemplo de configuración completa:
Bloque de código language java 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 language java @PreAuthorize( "@umuJwtLoaAuthenticator.isSubstantialLoA(authentication)" )
Advertenciainfo 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 language java @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 = "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 ) {Advertencia Repetimos: ESTA CONFIGURACIÓN POR MÉTODO VALIDARÁ EL NIVEL DEL CLAIM LOA EN EL ENDPOINT CON LA ANOTACIÓN PREAUTHORIZE.
...
| Combinación de Autenticación | LoA |
|---|---|
| LDAP (cuenta UM) | LOW |
| LDAP (cuenta UM) + MFA (OTP) | SUBSTANTIAL |
| CMN | LOW |
| CMN + MFA | SUBSTANTIAL |
| Cl@ve certificado | SUBSTANTIAL |
| Cl@ve PIN (lleva implícito el OTP) | SUBSTANTIAL |
| Cl@ve permanente | LOWSUBSTANTIAL |
| Cl@ve certificado + MFA | SUBSTANTIAL |
| Cl@ve PIN + MFA | SUBSTANTIAL |
| Cl@ve permanente + MFA | SUBSTANTIAL |
| *Cl@ve + DNIe | HIGH |
...