Versiones comparadas

Clave

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

...

LoA (Level of Assurance) es el grado de confiabilidad de la identidad obtenida por un usuario autenticado en un sistema, es decir, el nivel de seguridad de un usuario autenticado en un sistema mediante un mecanismo de autenticación concreto.

Por ejemplo, en nuestro contexto UMU, la identidad obtenida por un usuario autenticado en CAS con su correo y contraseña tendrá el nivel LoA más bajo (LOW).
El mismo usuario, autenticado en CAS con un certificado digital, obtendrá un nivel LoA medio (SUBSTANTIAL). 

Info

Para FundeWebJS, el nivel LoA vendrá definido como un claim en el token JWT - Oauth2 devuelto por CAS.


Esta guía detalla los pasos a configurar en nuestras APIs REST FundeWebJS para securizarlas permitiendo solo el acceso a las identidades con un nivel LoA mínimo.

...

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 endpoint: Configurar el nivel LoA de forma independiente para cada endpoint. 

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.

...

  1. En la clase con la configuración de seguridad (generalmente SecurityConfig.java), 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
    @Override
        protected void configure(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();
            http.csrf().disable();
        }


    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.",	content = @Content( schema = @Schema( implementation = AfiliacionDTO.class ) ) )
    				} )
    	@PreAuthorize( "@umuJwtLoaAuthenticator.isSubstantialLoA(authentication)" )
    	public ResponseEntity<AfiliacionDTO> getAfiliacionGente( @AuthenticationPrincipal Jwt jwt ) {
    
    


RESPUESTA DE ERROR

Cuando se intenta acceder a un endpoint securizado con un token sin el claim LoA mínimo (independientemente de la configuración elegida), se devolverá la siguiente información:

- Código HTTP: 401
- Cabecera en la respuesta: umu-authenticat: invalid_loa_claim 
- Cabecera en la respuesta: www-authenticate: Bearer error="invalid_loa_claim",error_description="Invalid LoA Claim. Excepted level 'SUBSTANTIAL' : Found level: 'LOW' ",error_uri="https://tools.ietf.org/html/rfc6750#section-3.1

...