Salut, mes amis! Demain, les premiers cours commenceront dans le nouveau fil du cours
"Developer on Spring Framework" . à cet égard, nous partageons traditionnellement des informations utiles sur le sujet.

Dans cet article, nous explorerons l'utilisation d'OAuth2 et de JWT conjointement avec Spring Boot et Spring Security.
Serveur d'autorisation
Un serveur d'autorisation est le composant le plus important de l'architecture de sécurité de l'API Web. Le serveur d'autorisation agit comme un point d'autorisation unique et permet à vos applications et points de terminaison HTTP de définir les fonctions de votre application.
Serveur de ressources
Le serveur d'autorisation fournit aux clients un jeton d'accÚs pour accéder aux points de terminaison HTTP du serveur de ressources. Un serveur de ressources est une collection de bibliothÚques qui contient des points de terminaison HTTP, des ressources statiques et des pages Web dynamiques.
OAuth2
OAuth2 est un protocole d'autorisation qui permet à un client (tiers) d'accéder aux ressources de votre application. Pour créer une application OAuth2, nous devons connaßtre le type de subvention (code d'autorisation), l'ID client et le secret client.
Jeton JWT
Un jeton JWT est un jeton Web JSON. Il est utilisé pour représenter des informations d'identification sécurisées (réclamations) entre deux parties. Vous pouvez trouver plus d'informations sur les jetons JWT sur
www.jwt.io.Nous allons créer une application OAuth2 à l'aide de jetons JWT, qui comprendra un serveur d'autorisation et un serveur de ressources.
Tout d'abord, nous devons ajouter les dépendances à notre fichier de construction.
Les utilisateurs Maven peuvent ajouter les dĂ©pendances suivantes Ă
pom.xml
.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
Note du traducteur - pour java de plus de 9 ans, vous devez également ajouter les dépendances suivantes: <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.2.11</version> </dependency>
Les utilisateurs Gradle peuvent ajouter les dépendances suivantes au fichier
build.gradle
.
compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') compile("org.springframework.security.oauth:spring-security-oauth2") compile('org.springframework.security:spring-security-jwt') compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191")
oĂč
- Spring Boot Starter Security - implémente Spring Security
- Spring Security OAuth2 - implémente les structures OAUTH2 pour le fonctionnement du serveur d'autorisation et du serveur de ressources.
- Spring Security JWT - GénÚre des jetons JWT
- Spring Boot Starter JDBC - accÚs à la base de données pour la vérification des utilisateurs.
- Spring Boot Starter Web - Fournit des points de terminaison HTTP.
- Base de données H2 - stocke les informations utilisateur pour l'authentification et l'autorisation.
Le fichier
pom.xml
complet
pom.xml
illustré ci-dessous.
<?xml version = "1.0" encoding = "UTF-8"?> <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint</groupId> <artifactId>websecurityapp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>websecurityapp</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Gradle â build.gradle
buildscript { ext { springBootVersion = '1.5.9.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' group = 'com.tutorialspoint' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') compile("org.springframework.security.oauth:spring-security-oauth2") compile('org.springframework.security:spring-security-jwt') compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191") }
Maintenant, ajoutez les annotations
@EnableAuthorizationServer
et
@EnableResourceServer
au fichier d'application Spring Boot principal pour que l'application fonctionne Ă la fois comme serveur d'autorisation et serveur de ressources.
Ajoutez également un simple point de terminaison HTTP (/ produits) pour accéder à l'API protégée par Spring Security à l'aide d'un jeton JWT.
package com.tutorialspoint.websecurityapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableAuthorizationServer @EnableResourceServer @RestController public class WebsecurityappApplication { public static void main(String[] args) { SpringApplication.run(WebsecurityappApplication.class, args); } @RequestMapping(value = "/products") public String getProductName() { return "Honey"; } }
Définissez une classe POJO pour stocker les informations d'authentification des utilisateurs.
package com.tutorialspoint.websecurityapp; import java.util.ArrayList; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; public class UserEntity { private String username; private String password; private Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Collection<GrantedAuthority> getGrantedAuthoritiesList() { return grantedAuthoritiesList; } public void setGrantedAuthoritiesList(Collection<GrantedAuthority> grantedAuthoritiesList) { this.grantedAuthoritiesList = grantedAuthoritiesList; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
Ensuite, pour l'authentification, ajoutez la classe CustomUser, qui étend
org.springframework.security.core.userdetails.User
.
package com.tutorialspoint.websecurityapp; import org.springframework.security.core.userdetails.User; public class CustomUser extends User { private static final long serialVersionUID = 1L; public CustomUser(UserEntity user) { super(user.getUsername(), user.getPassword(), user.getGrantedAuthoritiesList()); } }
Créez une
@Repository-
pour récupérer les informations utilisateur de la base de données et ajoutez les privilÚges ROLE_SYSTEMADMIN. Cette classe sera également utilisée dans
CustomDetailsService
.
package com.tutorialspoint.websecurityapp; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Repository; @Repository public class OAuthDao { @Autowired private JdbcTemplate jdbcTemplate; public UserEntity getUserDetails(String username) { Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); String userSQLQuery = "SELECT * FROM USERS WHERE USERNAME=?"; List<UserEntity> list = jdbcTemplate.query(userSQLQuery, new String[] { username }, (ResultSet rs, int rowNum) -> { UserEntity user = new UserEntity(); user.setUsername(username); user.setPassword(rs.getString("PASSWORD")); return user; }); if (list.size() > 0) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_SYSTEMADMIN"); grantedAuthoritiesList.add(grantedAuthority); list.get(0).setGrantedAuthoritiesList(grantedAuthoritiesList); return list.get(0); } return null; } }
Pour appeler le référentiel DAO, vous pouvez créer votre
UserDetailsService
, héritant de
org.springframework.security.core.userdetails.UserDetailsService
, comme illustré ci-dessous.
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service public class CustomDetailsService implements UserDetailsService { @Autowired OAuthDao oauthDao; @Override public CustomUser loadUserByUsername(final String username) throws UsernameNotFoundException { UserEntity userEntity = null; try { userEntity = oauthDao.getUserDetails(username); CustomUser customUser = new CustomUser(userEntity); return customUser; } catch (Exception e) { e.printStackTrace(); throw new UsernameNotFoundException("User " + username + " was not found in the database"); } } }
Ensuite, créez une
@onfiguration-
pour activer
Web Security
. Définissez les paramÚtres de chiffrement du mot de passe (
BCryptPasswordEncoder
) et le bean
AuthenticationManager
qu'il
BCryptPasswordEncoder
.
Cette classe
SecurityConfiguration
doit hériter de la classe
WebSecurityConfigurerAdapter
.
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; 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.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomDetailsService customDetailsService; @Bean public PasswordEncoder encoder() { return new BCryptPasswordEncoder(); } @Override @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customDetailsService).passwordEncoder(encoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.NEVER); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring(); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
Ajoutez maintenant une classe pour configurer OAuth2. Dans celui-ci, définissez l'ID client, le secret client, JwtAccessTokenConverter, les clés privées et publiques pour signer et vérifier le jeton, et configurer
ClientDetailsServiceConfigurer
pour des portées de jeton valides.
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @Configuration public class OAuth2Config extends AuthorizationServerConfigurerAdapter { private String clientid = "tutorialspoint"; private String clientSecret = "my-secret-key"; private String privateKey = "private key"; private String publicKey = "public key"; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Bean public JwtAccessTokenConverter tokenEnhancer() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(privateKey); converter.setVerifierKey(publicKey); return converter; } @Bean public JwtTokenStore tokenStore() { return new JwtTokenStore(tokenEnhancer()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore()) .accessTokenConverter(tokenEnhancer()); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient(clientid).secret(clientSecret).scopes("read", "write") .authorizedGrantTypes("password", "refresh_token").accessTokenValiditySeconds(20000) .refreshTokenValiditySeconds(20000); } }
Créez maintenant les clés privées et publiques en utilisant
openssl
.
Pour générer une clé privée, vous pouvez utiliser les commandes suivantes -
openssl genrsa -out jwt.pem 2048 openssl rsa -in jwt.pem
Pour clé publique -
openssl rsa -in jwt.pem -pubout
Pour Spring Boot antérieur à la version 1.5, ajoutez la propriété suivante au fichier
application.properties
(pour déterminer l'ordre de filtrage des ressources OAuth2).
security.oauth2.resource.filter-order=3
Si vous utilisez un fichier YAML, ajoutez ce qui suit.
security: oauth2: resource: filter-order: 3
Créez maintenant les
data.sql
schema.sql
et
data.sql
dans le
data.sql
schema.sql
aux
schema.sql
du
schema.sql
src/main/resources/directory
pour connecter l'application à la base de données H2.
Le fichier
schema.sql
ressemble Ă ceci:
CREATE TABLE USERS (ID INT PRIMARY KEY, USERNAME VARCHAR(45), PASSWORD VARCHAR(60)); data.sql: INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 1, 'tutorialspoint@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG'); INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 2, 'myemail@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG');
Remarque - Le mot de passe dans la table de base de donnĂ©es doit ĂȘtre stockĂ© au format Bcrypt Encoder.
Vous pouvez créer un fichier JAR exécutable et exécuter l'application Spring Boot à l'aide des commandes Maven ou Gradle suivantes.
Pour Maven, vous pouvez utiliser la commande ci-dessous -
mvn clean install
AprÚs «BUILD SUCCESS», vous pouvez trouver les fichiers JAR dans le répertoire
target
.
Pour Gradle, vous pouvez utiliser la commande -
gradle clean build
AprÚs «BUILD SUCCESSFUL», vous pouvez trouver les fichiers JAR dans le répertoire
build/libs
.
Exécutez maintenant le fichier JAR avec la commande -
java âjar <
JARFILE
>
L'application lancée dans Tomcat sur le port 8080.

Envoyez maintenant une demande POST via POSTMAN pour recevoir un jeton OAUTH2.
http://localhost:8080/oauth/token
Ajoutez maintenant les en-tĂȘtes de demande -
- Autorisation - Basique avec votre identifiant client et votre secret client.
- Type de contenu - application / x-www-form-urlencoded

Et demander des paramĂštres -
- grant_type = mot de passe
- nom d'utilisateur = votre nom
- mot de passe = votre mot de passe

Maintenant, exécutez et obtenez
access_token
comme indiqué.

CrĂ©ez maintenant une demande Ă l'API du serveur de ressources avec un jeton Bearer dans l'en-tĂȘte.

Nous obtenons le résultat comme indiqué ci-dessous.

Nous attendons vos commentaires, et nous vous informons également que jusqu'au 31 mai vous pouvez
rejoindre le cours à un prix spécial.