Présentation de la mise en œuvre de l'authentification des utilisateurs à l'aide de la sécurité Spring. Tout d'abord, après avoir expliqué comment hacher le mot de passe et vous inscrire en tant que nouveau membre, Nous allons vous montrer comment authentifier les utilisateurs à l'aide de la sécurité Spring.
Cette fois, nous avons confirmé l'opération dans l'environnement suivant.
DB
Tout d'abord, créez une table pour stocker votre nom d'utilisateur et votre mot de passe. Cette fois, nous allons créer une table USER avec le nom d'utilisateur (NAME), le mot de passe (PASSWORD) et l'ID sous forme de colonnes. Exécutez l'instruction SQL suivante pour créer la table USER.
CREATE TABLE USER(ID INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(64) NOT NULL, PASSWORD VARCHAR(64) NOT NULL);
L'important ici est de définir le nombre de caractères dans MOT DE PASSE à 60 ou plus. Le mot de passe est haché et enregistré dans la base de données, mais si le mot de passe est haché avec BCryptPasswordEncoder utilisé dans ce hachage, le nombre de caractères sera de 60 caractères, donc au moins 60 caractères sont requis pour la colonne de mot de passe cette fois.
Tout d'abord, injectez les dépendances de sécurité Spring pour utiliser la sécurité Spring. Ajoutez la dépendance suivante à Pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
L'injection d'une dépendance de sécurité Spring fera apparaître l'écran de connexion par défaut de la sécurité Spring lorsque vous lancerez l'application. À ce stade, l'écran de connexion par défaut suivant s'affiche.
Maintenant, affichons l'écran de connexion que vous avez créé dans la section suivante.
Ici, créez un écran de connexion, créez un contrôleur et créez WebSecurityConfig.java.
Tout d'abord, créez un écran de connexion.
Login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>S'identifier</title>
</head>
<body>
<form th:action="/" method="POST">
<table align="center">
<tr>
<td>
Nom d'utilisateur:
</td>
<td>
<input type="text" id="user" name="user"/>
</td>
</tr>
<tr>
<td>
mot de passe:
</td>
<td>
<input type="password" id="password" name="password"/>
</td>
</tr>
<tr>
<td>
</td>
<td align="right">
<button type="submit">S'identifier</button>
</td>
</tr>
<tr>
<td>
</td>
<td align="right">
<a href="/RegistrationForm">s'inscrire</a>
</td>
</tr>
</table>
</form>
</body>
</html>
Ensuite, créez un contrôleur.
LoginController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("/login")
public String showLoginForm(Model model) {
//Transition vers l'écran de connexion.
return "Login";
}
}
Ensuite, configurez avec java config. Créez une classe WebSecurityConfig pour la configuration. Cette classe hérite de WebSecurityConfigurerAdapter.
WebSecurityConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//Spécifiez la page de connexion.
//Tous les accès à la page de connexion sont autorisés.
http.formLogin()
.loginPage("/login")
.permitAll();
http.authorizeRequests()
.anyRequest().authenticated();
}
}
Dans loginPage (), spécifiez le chemin spécifié dans RequestMapping de la méthode showLoginForm () de la classe LoginController. En appelant permitAll (), vous pouvez accéder à la page de connexion même si vous n'êtes pas authentifié. Appelez anyRequest (). Authenticated () pour authentifier toutes les requêtes.
Lorsque vous avez terminé cette étape, l'écran de connexion que vous avez créé s'affiche comme indiqué ci-dessous.
Ensuite, nous mettrons en œuvre la fonction d'enregistrement des membres.
Ce chapitre décrit comment hacher le mot de passe et l'enregistrer dans la base de données. Cependant, comment créer un formulaire d'inscription d'adhésion et comment recevoir la valeur d'entrée du formulaire sont les mêmes que lorsque le mot de passe n'est pas haché, je vais donc l'omettre. Cette section se concentre sur la façon de hacher les mots de passe. Si vous voulez voir tout le code source, veuillez consulter github pour le code source.
Cette fois, BCryptPasswordEncoder est utilisé comme méthode de hachage. Ici, la classe PassswordEncoder est incluse dans deux packages, org.springframework.security.crypto.password et org.springframework.security.authentiction.encoding, mais ce dernier est obsolète, donc le premier J'utiliserai celui-là. Tout d'abord, ajoutez BCryptPasswordEncoder au bean avec java config.
WebSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//Spécifiez la page de connexion.
//Tous les accès à la page de connexion sont autorisés.
http.formLogin()
.loginPage("/login")
.permitAll();
http.authorizeRequests()
.anyRequest().authenticated();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Cette fois, les informations sur le membre sont insérées dans la base de données en définissant le mot de passe et le nom d'utilisateur dans les arguments de la méthode insertMemberInfo () de l'interface de mappage créée et en l'appelant. Hachez le mot de passe saisi dans le formulaire avant d'appeler la méthode insertMemberInfo ().
RegisterMemberService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.webapp.certificationtest.mapper.RegisterMemberMapper;
@Service
@Transactional
public class RegisterMemberService {
@Autowired
RegisterMemberMapper registerMemberMapper;
@Autowired
PasswordEncoder passwordEncoder;
/**
*Enregistrez les informations des membres dans DB.
*/
public void registerMember(MemberRegistrationEntity entity) {
//Hash le mot de passe et insérezMemberInfo()Défini sur l'objet à passer.
entity.setPassword(passwordEncoder.encode(entity.getPassword()));
registMemberMapper.insertMemberInfo(entity);
}
}
Ici, nous déclarons d'abord PasswordEncoder avec @ </ span> Autowired. Ensuite, après avoir appelé encode () de PasswordEncoder pour hacher le mot de passe, insérez le mot de passe dans la base de données.
Tout d'abord, ajoutez-le à WebSecurityConfig.java.
WebSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//Spécifiez la page de connexion.
//Tous les accès à la page de connexion sont autorisés.
http.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.usernameParameter("userName")
.passwordParameter("password")
.defaultSuccessUrl("/")
.permitAll();
//Ajouté lorsque la fonction d'enregistrement des membres est implémentée
http.authorizeRequests()
.antMatchers("/RegistrationForm").permitAll()
.antMatchers("/Register").permitAll()
.antMatchers("/Result").permitAll()
.anyRequest().authenticated();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Spécifiez l'URL à déplacer vers le processus d'authentification avec loginProcessingUrl (). Assurez-vous que cette URL correspond à la valeur de l'attribut action de la balise form du formulaire de connexion. Dans usernameParameter (), spécifiez la valeur de l'attribut name de la balise d'entrée qui place le nom d'utilisateur en html. Dans passwordParameter (), spécifiez la valeur de l'attribut name de la balise d'entrée qui place le mot de passe en html. Spécifie l'URL de la page vers laquelle accéder si la connexion réussit avec defaultSuccessUrl ().
Ensuite, modifiez l'action et saisissez le nom du formulaire dans Login.html.
Login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>S'identifier</title>
</head>
<body>
<form th:action="/authenticate" method="POST">
<table align="center">
<tr>
<td>
Nom d'utilisateur:
</td>
<td>
<input type="text" id="user" name="userName"/>
</td>
</tr>
<tr>
<td>
mot de passe:
</td>
<td>
<input type="password" id="password" name="password"/>
</td>
</tr>
<tr>
<td>
</td>
<td align="right">
<button type="submit">S'identifier</button>
</td>
</tr>
<tr>
<td>
</td>
<td align="right">
<a href="/RegistrationForm">s'inscrire</a>
</td>
</tr>
</table>
</form>
</body>
</html>
Ensuite, créez une classe pour mettre le nom d'utilisateur et le mot de passe obtenus à partir de la table USER.
Account.java
/**
*Une classe qui stocke les informations de membre requises pour la connexion.
*/
public class Account {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Ensuite, écrivez un mappeur qui obtient le nom d'utilisateur et le mot de passe de la table USER.
LoginMapper.java
import com.webapp.certificationtest.Account;
public interface LoginMapper {
public Account findAccount(String name);
}
LoginMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.webapp.certificationtest.mapper.LoginMapper">
<select id="findAccount" resultType="com.webapp.certificationtest.Account"
parameterType="String">
SELECT
NAME,
PASSWORD
FROM
USER
WHERE
NAME = #{userName}
</select>
</mapper>
Ensuite, créez une classe pour stocker les informations utilisateur. Il hérite de la classe User.
DbUserDetails.java
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
public class DbUserDetails extends User {
//Informations de l'utilisateur.
private final Account account;
public DbUserDetails(Account account,
Collection<GrantedAuthority> authorities) {
super(account.getName(), account.getPassword(),
true, true, true, true, authorities);
this.account = account;
}
public Account getAccount() {
return account;
}
}
Le deuxième argument du constructeur de classe DbUserDetails donne une liste d'autorisations à accorder à l'utilisateur.
Ensuite, créez la classe Service. Cette classe Service obtient la valeur de la table User et génère des UserDetails. L'authentification est effectuée en faisant correspondre les informations saisies par l'utilisateur dans le formulaire de connexion avec les détails de l'utilisateur générés ici.
DbUserDetailsService.java
import java.util.Collection;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.webapp.certificationtest.mapper.LoginMapper;
@Service
public class DbUserDetailsService implements UserDetailsService {
@Autowired
LoginMapper loginMapper;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String mailAddress)
throws UsernameNotFoundException {
//Obtenez des informations utilisateur de DB.
Account account = Optional.ofNullable(loginMapper.findOne(mailAddress))
.orElseThrow(() -> new UsernameNotFoundException("User not found."));
return new DbUserDetails(account, getAuthorities(account));
}
/**
*Définissez la plage d'autorité donnée à cet utilisateur lorsque l'authentification est réussie.
* @compte param Informations utilisateur obtenues auprès de DB.
* @return Une liste de plages de privilèges.
*/
private Collection<GrantedAuthority> getAuthorities(Account account) {
//Définissez la plage d'autorité donnée à l'utilisateur lorsque l'authentification est réussie.
return AuthorityUtils.createAuthorityList("ROLE_USER");
}
}
Si rien ne peut être extrait de la table User, lancez une UsernameNotFoundExceptionw. Dans l'argument UsernameNotFoundException, spécifiez le message lorsque le nom d'utilisateur n'existe pas dans la table User. Dans getAuthorities (), définissez les autorisations données à l'utilisateur obtenues à partir de la table User. Modifiez cette méthode si nécessaire. Si vous souhaitez donner plusieurs autorisations, ajoutez-les à l'argument de createAuthorityList () séparés par des virgules.
Ensuite, ajoutez à WebSecurityConfig.java pour l'authentification.
WebSecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
//Spécifiez la page de connexion.
//Tous les accès à la page de connexion sont autorisés.
http.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.usernameParameter("userName")
.passwordParameter("password")
.defaultSuccessUrl("/")
.permitAll();
http.csrf().disable().authorizeRequests()
.antMatchers("/RegistrationForm").permitAll()
.antMatchers("/Register").permitAll()
.antMatchers("/Result").permitAll()
.anyRequest().authenticated();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
void configureAuthenticationManager(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
}
Enfin, ajoutez-le à LoginController.java.
LoginController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
/**
*Transit vers le formulaire de connexion.
*/
@RequestMapping("/login")
public String showLoginForm(Model model) {
//Transition vers l'écran de connexion.
return "Login";
}
/**
*Accédez à la page principale.
*Si la connexion réussit, cette méthode sera appelée.
*/
@RequestMapping("/")
public String login(Model model) {
//Page d'accueil.
return "index";
}
}
Créez un écran à afficher après la connexion.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page d'accueil</title>
</head>
<body>
Ceci est la page principale.
</body>
</html>
Vérifiez le fonctionnement.
Le premier est l'inscription des membres.
Entrez votre nom d'utilisateur et votre mot de passe pour vous inscrire.
Lorsque l'enregistrement de l'adhésion est terminé, le mot de passe est haché et inséré dans la base de données de cette manière.
Vient ensuite la connexion.
Entrez le nom d'utilisateur et le mot de passe que vous avez enregistrés précédemment.
J'ai pu me connecter et accéder à la page principale.
Le code source jusqu'à présent est répertorié sur github, donc si vous voulez les voir tous, veuillez le voir. Si vous avez des questions, n'hésitez pas à me contacter sur Twitter.
Recommended Posts