Le socle technique (ou technologique)

  1. Spring framework | Spring Boot | Spring Security
  2. OpenID connect | OAuth 2 | Json Web Token (JWT)

 

Le workflow NCConnect

 

Spring framework

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

Spring Security

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Framework

Spring MVC

Spring Data

...

Spring Boot

Spring Security

User

Spring Security

Répond à deux problématiques de sécurité :

  • l'authentification, et
  • les autorisations.

Spring Security

l'authentification

public interface AuthenticationManager {

    /**

    * Attempts to authenticate the passed {@link Authentication} object, returning a

    * fully populated <code>Authentication</code> object (including granted authorities)

    * if successful.

    */
 
    Authentication authenticate(Authentication authentication) throws AuthenticationException;

}

Elle s'appuie sur des AuthenticationProviders au travers d'un ProviderManager, à la DTSI :

  • connect,
  • facebook,
  • gemini,
  • google,
  • linkedin, et
  • yahoo

AuthenticationProviders are usually tried in order until one provides a non-null response. A non-null response indicates the provider had authority to decide on the authentication request and no further providers are tried.

Spring Security

les autorisations

Elles sont incluses dans l'objet Authentication retourné par la méthode authenticate(...) sous forme d'une Collection<? extends GrantedAuthority>

 

Cette opération est donc bien exécutée lors de l'authentification de l'utilisateur mais reste une opération indépendante de l'authentification.

Spring Security

les autorisations (exemple)

@Override

public Authentication authenticate(Authentication authentication) throws AuthenticationException {

    String name = authentication.getName();

    String password = authentication.getCredentials().toString();

    UserVO user = userDAO.findByUsername(name);

    if (user == null) {

        throw new BadCredentialsException("Authentication failed for " + name);

    }

    List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

    if (new PasswordEncoderImpl().matches(password, user.getPassword())) {

        List<AuthorisationVO> roles = user.getRoles();

        for (AuthorisationVO item : roles) {

            grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + item.getAuthorisation()));

        }

    }

}

Il est possible d'utiliser une implémentation de UserDetailService et UserDetails. Il faut cependant faire attention car ces implémentation ne sont pas utilisées directement pas Spring Security (qui utilise Authentication). Elles sont en fait utilisées pour avoir une représentation sémantique et plus large de l'utilisateur (incluant des informations qui ne relèvent pas toujours de la gestion de la sécurité).

Spring Security

Sécurisation des API Rest

Annotations :

  • @Secured (type, méthode), et
  • @PreAuthorize (type, méthode)

 

Cf. GrantedAuthority.getAuthority():String si le niveau d'accès peut être représenté par une simple chaîne de caractères, ou en passant par un AccessDecisionManager pour une mise en oeuvre plus élaborée.

 

En complèment, pour le cas particulier de Spring Data Rest, qui expose par défaut toutes les méthodes des interfaces étendues :

@RestResource (type, méthode, attribut), et

@RepositoryRestResource (type),

permettent au travers de l'attribut exported = false de ne pas exposer les méthodes qui ne doivent pas l'être !

Spring Security

Sécurisation des API Rest

Ce qui suppose que la sécurité est également configurée au niveau de l'application :

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        (...)

    }


    @Override

    protected void configure(HttpSecurity http) throws Exception {

        http

          .sessionManagement()

          .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

          .and()

          .authorizeRequests()

          .antMatchers("/login**").permitAll()

          (...)

          .anyRequest().authenticated()

          .and()

          (...)

    }

}

 

Spring Security

A retenir

- Authentification vs. autorisations

- Références :

    - La documentation de référence

    - La javadoc

OpenID Connect Core

cf. OpenID Connect Core 1.0 specification

OAuth 2.0 Authorization Framework

cf. IETF RFC 6749

JSON Web Token (JWT)

cf. IETF RFC 7519

User

JWT

OAuth 2.0

OpenID Connect Core

(1)

(1)

Supporte nativement OAuth 2.0

Spring Framework

Spring MVC

Spring Data

...

Spring Boot

Spring Security

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 [RFC6749] protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

+
+

Ces trois éléments sont donc indissociables dans une approche OpenID Connect...

Le mécanisme d'authentification et d'autorisation peut prendre trois formes, chacune d'entre-elles déterminant la façon dont l'ID Token et l'Access Token sont renvoyés au client [RFC 6749 - The OAuth 2.0 Authorization Framework § 3.1.1 Response Type]:

Authorization Code Flow,

Implicit Flow, et

Hybrid Flow.

L'implémentation retenue dans NC Connect est Authorization Code Flow (response_type=code).

+
+

Authorization Code Flow

+
+

3 endpoints obligatoires :

  • Authorization
  • Token
  • User info

3 endpoints optionels :

  • Discovery
  • Session management
  • Client registration
+
+

Type de token par point d'accès

Identity Access Refresh Authorization
Authorization
Token

Exemple :

eyJhbGciOiJSUzUxMiJ9.eyJvYXV0aDJfcHJvdmlkZXIiOiJnZW1pbmkiLCJpc3MiOiJjb25uZWN0LXJlc291cmNlcyIsImlhdCI6MTU4MDA4NjU0MywicHJuIjoiZXlKaGJHY2lPaUpTVXpVeE1pSjkuZXlKemRXSWlPaUpoWjJWdWRFRkVMemd4TVRVM01qQm1MV1poTlRrdE5HTTNaUzFpWVRneUxURmpNR1l6TjJFeE5qWmtaU0lzSW01aGJXVWlPaUpFYVdScFpYSWdWa0ZPUkVWU1UxUlBTMFZPSWl3aVpXMWhhV3dpT2lKa2FXUnBaWEl1ZG1GdVpHVnljM1J2YTJWdUxuQnlaWE4wWVhSaGFYSmxRR2R2ZFhZdWJtTWlMQ0puYVhabGJsOXVZVzFsSWpvaVJHbGthV1Z5SWl3aVptRnRhV3g1WDI1aGJXVWlPaUpXUVU1RVJWSlRWRTlMUlU0aUxDSmxiV0ZwYkY5MlpYSnBabWxsWkNJNmRISjFaWDAuSXR5QXI4RHlaREY5Rnp1Tnhxa3JHWndQNWllZl9ER1Bha2RoZGM0SXJfSF9OcWtzT1FidjQ2OTQ2dFpRMnlQNktCM0ZnVE9HTFh5eHlYd3Qwd01GSzJ4bi1RQ2lXNi1QVmNSVm1BTHJiRmtqLXplNHdlQkV3ZzllRVJ1ZGcwSkc0SFVLOW5oQWRlWXdPMzJuZnhpbkpoUHhRMFFDSE5ZUXcwb2UwelZIRUgxenR1MXRJdkxDQjZJNG82bHlhcWM2TllHTzNqT3lkbE9GcFY3UlpaTzNLbVRzQVlfZnJoWDlVNVVzcVAzSlBKeVU4Wi1Wa3RpXzVMZUU0VzJERHlkbG5yZ3pVSjhBaVZ3UkQ1ZTBqRWlqVE5hb2M2cy1EQjFSdzlDMmZVR2JxYkVyR0c4XzAtVTZJTWNUUmxNZnZLZVNkR2kxWUdTRGpzTTZ3OWkzX3gyZlpRIiwianRpIjoiM2UzOWJkYWMtMGJlMC00ZjQ1LTk0MzgtMGY4MzBmMDU1OTQ3IiwiYXVkIjoiY29ubmVjdC1yZXNvdXJjZXMiLCJleHAiOjE1ODAwODc0NDIsImFjY2Vzc190b2tlbiI6ImV5SmhiR2NpT2lKU1V6VXhNaUo5LmV5SmhkV1FpT2lKaFkyTmxjM010ZEc5clpXNGlMQ0p6WTI5d1pTSTZXeUp2Y0dWdWFXUWlYU3dpYVhOeklqb2laMlZ0YVc1cElpd2laWGh3SWpveE5UZ3dNRGczTkRRekxDSjFjMlZ5SWpwN0ltbGtJam9pT0RFeE5UY3lNR1l0Wm1FMU9TMDBZemRsTFdKaE9ESXRNV013WmpNM1lURTJObVJsSWl3aWNISnZkbWxrWlhKSlpDSTZJbUZuWlc1MFFVUWlMQ0ptYVhKemRFNWhiV1VpT2lKRWFXUnBaWElpTENKc1lYTjBUbUZ0WlNJNklsWkJUa1JGVWxOVVQwdEZUaUlzSW1WdFlXbHNJam9pWkdsa2FXVnlMblpoYm1SbGNuTjBiMnRsYmk1d2NtVnpkR0YwWVdseVpVQm5iM1YyTG01akluMHNJbUYxZEdodmNtbDBhV1Z6SWpwYklsSlBURVZmVlZORlVpSmRMQ0pxZEdraU9pSXpNVEF5TWpKaVl5MDRZV0kxTFRReFpHWXRPR1V4WmkxbU5qSXlORGMzTldFNFpqRWlMQ0pqYkdsbGJuUmZhV1FpT2lKamIyNXVaV04wTFdGa2JXbHVMWE5vWVdSdmR5SjkuVW1mQko4Zng1NHljaUpFYzVRLW1kOGRfZGJXLVpVZ0prOHFKWUpYN0JtOVNER2FsRF9MT3plekxUOVg3ODFIRlJGSkNvMzVBUVhkQ2YtVDd0T2Q5Z0VuT25Jbnh1WWttNlNsMFlJVFdCajh4Si1hWk50cWRVbnZGTjhyRWJqTlZFbnY0MHREOHFReFRXbGZRb1VTWjBFMGJFRkJlY1lHWXVTWnZldmVscDgtU3JXeU5vOV9lc1Rsb0JiQVI3TnBoMjd5LVB0LTUzdTk1NUVLdTJ6QmdSaG1mdHdmVjBtTmFGN3JxR0duR2VjcUtvUlRTOVU3dHdzdTlrc1hKVTJzOUF6dlNCUTRJdWJqVElKMmdzWUtVYURyaFBhZVVVVFMyVWJOaXhwVHNaN1JNUm10TkJpWXZ2X21icC14Ry0zTXNhQzI3aDBwSGY3TDY0WmlqV2ZJTTNnIiwicmVmcmVzaF90b2tlbiI6ImV5SmhiR2NpT2lKU1V6VXhNaUo5LmV5SmhkV1FpT2lKeVpXWnlaWE5vTFhSdmEyVnVJaXdpYzJOdmNHVWlPbHNpYjNCbGJtbGtJbDBzSW1GMGFTSTZJak14TURJeU1tSmpMVGhoWWpVdE5ERmtaaTA0WlRGbUxXWTJNakkwTnpjMVlUaG1NU0lzSW1semN5STZJbWRsYldsdWFTSXNJbVY0Y0NJNk1UVTRNREUwTkRRd01Dd2lkWE5sY2lJNmV5SnBaQ0k2SWpneE1UVTNNakJtTFdaaE5Ua3ROR00zWlMxaVlUZ3lMVEZqTUdZek4yRXhOalprWlNJc0luQnliM1pwWkdWeVNXUWlPaUpoWjJWdWRFRkVJaXdpWm1seWMzUk9ZVzFsSWpvaVJHbGthV1Z5SWl3aWJHRnpkRTVoYldVaU9pSldRVTVFUlZKVFZFOUxSVTRpTENKbGJXRnBiQ0k2SW1ScFpHbGxjaTUyWVc1a1pYSnpkRzlyWlc0dWNISmxjM1JoZEdGcGNtVkFaMjkxZGk1dVl5SjlMQ0poZFhSb2IzSnBkR2xsY3lJNld5SlNUMHhGWDFWVFJWSWlYU3dpYW5ScElqb2lOR1EzT1RWa1ptTXROemMxTnkwMFpUWTFMVGhqTVdRdFl6VXhaVFZrWkRabFpXWmtJaXdpWTJ4cFpXNTBYMmxrSWpvaVkyOXVibVZqZEMxaFpHMXBiaTF6YUdGa2IzY2lmUS5YekFFbE96b2p4cUo3eGVpMlVJMFlLNFVDajZNVWJSWldNVWdqVVc5RWhzWnNGMlV5TGhSaW0xbi1XSG9yWDhKMi1qTjdBenpOc3NTR0RxS2NzbmZiVkYtRUlrNm1KazhkYnQ3Y25ZQU84RlRldlBCREhVZEd3NFhHSUk5c05RaWdHNGZEVkc5NU9YSzRSOVhYZXBrLWhyUmxrT1h0azFLeHo2azh3Ry1uNDRrZ3g1VzRiV055a3NQaTVWVExzZzlsMUx6akctMFVRLUFudWtVMEhmWGFKbW84NmJFVmdESm9FRjZzVkVITW1INDF6N0JWY2hPRmRDYnhnZHBQODhGYjdJNmtfYmRhN3Q3NmFDeHlyVTU0SnNOSWNla1FfUDlrbkx2ZDF4RU9lT3dOdFhoS1dza3BlbHVNZ0puanR3eFlKSG5JNkx4TG5DWlhTSzBZUVdocVEiLCJzY29wZSI6Im9wZW5pZCJ9.bVTBOB9EfuNOOoYsTPFJocrvsRrVcGjyfKCXmZ-D2E0swEKrkkJCLgcQhwU1d2Qr5AO4axaMUnf_96CdsuNCYq6SJHuKyALK9lEyMDvrRIm9jYhcRMrqtYsMNv6Vb_to-PnrIeOl0q9RyMM50wWfu7Ez2UNLfeAlEEpYQSwdwRD1qw4QM4t0F7gj78W79cPSJHubwZRkebEWJQsOKSMAMJ8sXSCJtpBk4qIsybYByLdDs66n4TMuYVUCD9_Ex2Xio7kDKE8anHpKzINFtDSl7Lz6oSUSnGrcKnxeGuKtxJwc3DD_DPkVzx-fdwfvZZRSqeKZS-Sq-mERMZJkP-hj6A

Exemple (suite) :

    header (Algorythme & type de token) :

 

 

    

 

 

 

 

{
  "alg": "RS512"
}

Exemple (suite) :

    payload :

 

 

    

 

 

 

 

{
  "oauth2_provider": "gemini",
  "iss": "connect-resources",
  "iat": 1580086543,
  "prn": "eyJhbGciOiJSUzUxMiJ9.eyJzdWIiOiJhZ2VudEFELzgxMTU3MjBmLWZhNTktNGM3ZS1iYTgyLTFjMGYzN2ExNjZkZSIsIm5hbWUiOiJEaWRpZXIgVkFOREVSU1RPS0VOIiwiZW1haWwiOiJkaWRpZXIudmFuZGVyc3Rva2VuLnByZXN0YXRhaXJlQGdvdXYubmMiLCJnaXZlbl9uYW1lIjoiRGlkaWVyIiwiZmFtaWx5X25hbWUiOiJWQU5ERVJTVE9LRU4iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZX0.ItyAr8DyZDF9FzuNxqkrGZwP5ief_DGPakdhdc4Ir_H_NqksOQbv46946tZQ2yP6KB3FgTOGLXyxyXwt0wMFK2xn-QCiW6-PVcRVmALrbFkj-ze4weBEwg9eERudg0JG4HUK9nhAdeYwO32nfxinJhPxQ0QCHNYQw0oe0zVHEH1ztu1tIvLCB6I4o6lyaqc6NYGO3jOydlOFpV7RZZO3KmTsAY_frhX9U5UsqP3JPJyU8Z-Vkti_5LeE4W2DDydlnrgzUJ8AiVwRD5e0jEijTNaoc6s-DB1Rw9C2fUGbqbErGG8_0-U6IMcTRlMfvKeSdGi1YGSDjsM6w9i3_x2fZQ",
  "jti": "3e39bdac-0be0-4f45-9438-0f830f055947",
  "aud": "connect-resources",
  "exp": 1580087442,
  "access_token": "eyJhbGciOiJSUzUxMiJ9.eyJhdWQiOiJhY2Nlc3MtdG9rZW4iLCJzY29wZSI6WyJvcGVuaWQiXSwiaXNzIjoiZ2VtaW5pIiwiZXhwIjoxNTgwMDg3NDQzLCJ1c2VyIjp7ImlkIjoiODExNTcyMGYtZmE1OS00YzdlLWJhODItMWMwZjM3YTE2NmRlIiwicHJvdmlkZXJJZCI6ImFnZW50QUQiLCJmaXJzdE5hbWUiOiJEaWRpZXIiLCJsYXN0TmFtZSI6IlZBTkRFUlNUT0tFTiIsImVtYWlsIjoiZGlkaWVyLnZhbmRlcnN0b2tlbi5wcmVzdGF0YWlyZUBnb3V2Lm5jIn0sImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiIzMTAyMjJiYy04YWI1LTQxZGYtOGUxZi1mNjIyNDc3NWE4ZjEiLCJjbGllbnRfaWQiOiJjb25uZWN0LWFkbWluLXNoYWRvdyJ9.UmfBJ8fx54yciJEc5Q-md8d_dbW-ZUgJk8qJYJX7Bm9SDGalD_LOzezLT9X781HFRFJCo35AQXdCf-T7tOd9gEnOnInxuYkm6Sl0YITWBj8xJ-aZNtqdUnvFN8rEbjNVEnv40tD8qQxTWlfQoUSZ0E0bEFBecYGYuSZvevelp8-SrWyNo9_esTloBbAR7Nph27y-Pt-53u955EKu2zBgRhmftwfV0mNaF7rqGGnGecqKoRTS9U7twsu9ksXJU2s9AzvSBQ4IubjTIJ2gsYKUaDrhPaeUUTS2UbNixpTsZ7RMRmtNBiYvv_mbp-xG-3MsaC27h0pHf7L64ZijWfIM3g",
  "refresh_token": "eyJhbGciOiJSUzUxMiJ9.eyJhdWQiOiJyZWZyZXNoLXRva2VuIiwic2NvcGUiOlsib3BlbmlkIl0sImF0aSI6IjMxMDIyMmJjLThhYjUtNDFkZi04ZTFmLWY2MjI0Nzc1YThmMSIsImlzcyI6ImdlbWluaSIsImV4cCI6MTU4MDE0NDQwMCwidXNlciI6eyJpZCI6IjgxMTU3MjBmLWZhNTktNGM3ZS1iYTgyLTFjMGYzN2ExNjZkZSIsInByb3ZpZGVySWQiOiJhZ2VudEFEIiwiZmlyc3ROYW1lIjoiRGlkaWVyIiwibGFzdE5hbWUiOiJWQU5ERVJTVE9LRU4iLCJlbWFpbCI6ImRpZGllci52YW5kZXJzdG9rZW4ucHJlc3RhdGFpcmVAZ291di5uYyJ9LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiNGQ3OTVkZmMtNzc1Ny00ZTY1LThjMWQtYzUxZTVkZDZlZWZkIiwiY2xpZW50X2lkIjoiY29ubmVjdC1hZG1pbi1zaGFkb3cifQ.XzAElOzojxqJ7xei2UI0YK4UCj6MUbRZWMUgjUW9EhsZsF2UyLhRim1n-WHorX8J2-jN7AzzNssSGDqKcsnfbVF-EIk6mJk8dbt7cnYAO8FTevPBDHUdGw4XGII9sNQigG4fDVG95OXK4R9XXepk-hrRlkOXtk1Kxz6k8wG-n44kgx5W4bWNyksPi5VTLsg9l1LzjG-0UQ-AnukU0HfXaJmo86bEVgDJoEF6sVEHMmH41z7BVchOFdCbxgdpP88Fb7I6k_bda7t76aCxyrU54JsNIcekQ_P9knLvd1xEOeOwNtXhKWskpeluMgJnjtwxYJHnI6LxLnCZXSK0YQWhqQ",
  "scope": "openid"
}

Exemple (suite) :

    access-token:

 

 

    

 

 

 

 

{
  "aud": "access-token",
  "scope": [
    "openid"
  ],
  "iss": "gemini",
  "exp": 1580087443,
  "user": {
    "id": "8115720f-fa59-4c7e-ba82-1c0f37a166de",
    "providerId": "agentAD",
    "firstName": "Didier",
    "lastName": "VANDERSTOKEN",
    "email": "didier.vanderstoken.prestataire@gouv.nc"
  },
  "authorities": [
    "ROLE_USER"
  ],
  "jti": "310222bc-8ab5-41df-8e1f-f6224775a8f1",
  "client_id": "connect-admin-shadow"
}

JWT constitue l'enveloppe  standard d'échange des informations (des tokens).


Il est constitué de 3 parties : 

  • header,
  • payload, et
  • signature


Questions

RedStone - DTSI - NC-Connect

By Didier Vanderstoken

RedStone - DTSI - NC-Connect

  • 526