Maison > Java > javaDidacticiel > Comment utiliser SpringBoot+SpringSecurity pour implémenter l'authentification d'autorisation basée sur des données réelles

Comment utiliser SpringBoot+SpringSecurity pour implémenter l'authentification d'autorisation basée sur des données réelles

王林
Libérer: 2023-05-13 19:34:20
avant
976 Les gens l'ont consulté

(1) Présentation

Spring Security est un cadre d'authentification et de contrôle d'accès puissant et hautement personnalisable qui fait principalement deux choses : l'authentification et l'autorisation. J'ai déjà écrit un blog sur Spring Security, mais à cette époque, je n'avais présenté qu'un cas basé sur des données fictives. Dans ce numéro, je présenterai la mise en œuvre de l'authentification et de l'autorisation basées sur des données réelles.

(2) Construction préliminaire du projet

Afin de mieux démontrer SpringSecurity, nous construisons d'abord un projet Web simple. Introduire la dépendance thymeleaf

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-thymeleaf</artifactid>
</dependency>
<dependency>
    <groupid>org.thymeleaf</groupid>
    <artifactid>thymeleaf-spring5</artifactid>
</dependency>
<dependency>
    <groupid>org.thymeleaf.extras</groupid>
    <artifactid>thymeleaf-extras-java8time</artifactid>
</dependency>
Copier après la connexion

Créer une page de connexion, une page d'accueil, puis plusieurs pages d'affichage de différents niveaux : login.html

nbsp;html>


    <meta>
    <title>登陆页</title>


<div>
    <form>
        <h3>登陆页</h3>
        <input>
        <input>
        <button>登陆</button>
    </form>
</div>

Copier après la connexion

index.html

nbsp;html>


    <meta>
    <title>首页</title>


<div>
    <h3>首页</h3>
    <a>登陆</a>
    <div>
        <div>
            <h4>level1</h4>
            <a>level-1-1</a>
            <hr>
            <a>level-1-2</a>
        </div>
        <div>
            <h4>level2</h4>
            <a>level-2-1</a>
            <hr>
            <a>level-2-2</a>
        </div>
        <div>
            <h4>level3</h4>
            <a>level-3-1</a>
            <hr>
            <a>level-3-2</a>
        </div>
    </div>
</div>

Copier après la connexion

De plus, il y a plusieurs pages de différents niveaux

Comment utiliser SpringBoot+SpringSecurity pour implémenter lauthentification dautorisation basée sur des données réelles

respectivement Écrivez votre numéro correspondant dans le corps.

nbsp;html>


    <meta>
    <title>Title</title>


level-1-1

Copier après la connexion

Enfin, écrivez un contrôleur pour recevoir la demande :

@Controller
public class RouteController {

    @RequestMapping({"/","/index"})
    public String index(){
        return "index";
    }

    @RequestMapping("/login")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id")String id){
        return "level1/"+id;
    }
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id")String id){
        return "level2/"+id;
    }
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id")String id){
        return "level3/"+id;
    }
}
Copier après la connexion

L'effet final est le suivant :

Comment utiliser SpringBoot+SpringSecurity pour implémenter lauthentification dautorisation basée sur des données réelles

Enfin, les pages de niveau avec différents niveaux peuvent être sautées selon différentes autorisations.

Comment utiliser SpringBoot+SpringSecurity pour implémenter lauthentification dautorisation basée sur des données réelles

L'arrière-plan est implémenté sur la base de données Mybatis et Mysql, donc en plus d'introduire les dépendances SpringSecurity, nous devons également introduire les dépendances liées à Mybatis :

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-security</artifactid>
</dependency>
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-jdbc</artifactid>
</dependency>
<dependency>
    <groupid>mysql</groupid>
    <artifactid>mysql-connector-java</artifactid>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupid>org.mybatis.spring.boot</groupid>
    <artifactid>mybatis-spring-boot-starter</artifactid>
    <version>2.1.3</version>
</dependency>
Copier après la connexion

Ajouter des informations relatives à la source de données dans le fichier de configuration, ainsi que Mybatis configuration :

spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis.mapper-locations=classpath:mapper/*.xml
Copier après la connexion

(3) Implémentation de l'authentification et de l'autorisation

3.1 Conception de la structure de la table

L'authentification et l'autorisation doivent être divisées en deux tables dans la conception de la table. Une table stocke les informations utilisateur, y compris les mots de passe, etc., et l'autre table stocke. Les informations d'autorisation sont également requises. Un tableau établit l'association entre les utilisateurs et les autorisations, donnant la structure du tableau final :

CREATE TABLE `roles` (
  `id` int(4) NOT NULL,
  `rolename` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `sysuser` (
  `id` int(4) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `user_role` (
  `id` int(4) NOT NULL,
  `user_id` int(4) DEFAULT NULL,
  `role_id` int(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Copier après la connexion

L'étape suivante concerne les classes d'entités, les interfaces Mapper et les fichiers XML pour ces trois tableaux. regardez le code, principalement pour implémenter un passe utilisateur Opérations pour rechercher les utilisateurs et les autorisations associées par nom :

@Data
public class Roles {
    private Integer id;
    private String roleName;
}

@Data
public class SysUser {
    private Integer id;
    private String userName;
    private String password;
    private List<roles> roles;
}</roles>
Copier après la connexion

Interface Mapper :

public interface UserMapper {
    public SysUser getUserByUserName(@Param("userName") String userName);
}
Copier après la connexion

implémentation xml :

<?xml  version="1.0" encoding="UTF-8" ?>
nbsp;mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper>
    <resultmap>
        <id></id>
        <result></result>
        <result></result>
        <collection>
            <result></result>
        </collection>
    </resultmap>
    <select>
        select sysuser.*,roles.rolename
        from sysuser
        LEFT JOIN user_role on sysuser.id= user_role.user_id
        LEFT JOIN roles on user_role.role_id=roles.id
        where username= #{userName}
    </select>
</mapper>
Copier après la connexion

3.2 Processus d'authentification

Le processus d'authentification de SpringSecurity est comme ça, trouvez d'abord dans la base de données via le nom d'utilisateur ou un autre identifiant unique. Pour cet utilisateur, le mot de passe de l'utilisateur est stocké dans un cryptage asymétrique. Après avoir obtenu l'utilisateur, le mot de passe transmis par la réception est crypté et comparé aux champs cryptés de la base de données pour réussir l'authentification.

La première étape du processus ci-dessus, pour rechercher l'utilisateur par nom d'utilisateur, doit être implémentée via le service Service, et ce service Service doit hériter de l'interface UserDetailsService dans Spring Security. Cette interface renvoie un objet SpringSecurity User.

@Service
public class UserService implements UserDetailsService {

    @Resource
    private UserMapper userMapper;
    //根据用户名找到对应的用户信息
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        SysUser sysUser = userMapper.getUserByUserName(s);
        if (sysUser!=null){
            List<grantedauthority> roles=new ArrayList();
            sysUser.getRoles().stream().forEach(x->{
                roles.add(new SimpleGrantedAuthority(x.getRoleName()));
            });
            return new User(sysUser.getUserName(),sysUser.getPassword(),roles);
        }
        throw new UsernameNotFoundException("用户未找到");
    }
}</grantedauthority>
Copier après la connexion

3.3 Configuration de l'interception de sécurité

Après avoir terminé les étapes ci-dessus, commencez à configurer la sécurité. Écrivez une méthode de configuration SecurityConfig Le niveau de code est très simple. Lorsque l'authentification est transmise à l'objet userService, le mot de passe est retiré de la base de données et. le frontal sera automatiquement transmis au mot de passe pour comparaison. Dans le même temps, la collection de rôles est également transmise dans userService et différentes autorisations peuvent être attachées à différentes pages au point d'autorisation.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;
    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人都能访问,level页面只有有权限的人才能访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认跳到登陆页,默认会重定向到/login
        http.formLogin();
    }

    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());

    }
}
Copier après la connexion

3.4 Autres points à noter

La méthode de cryptage des mots de passe que j'ai utilisée lors de l'authentification est BCryptPasswordEncoder, donc les mots de passe stockés dans la base de données doivent également être cryptés. La méthode courante consiste à crypter et à stocker les mots de passe de la même manière lors de l'inscription. . Entrez dans la base de données :

String password="xxx";
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode=bCryptPasswordEncoder.encode(password);
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal