Springsecurity-Berechtigungsverwaltung

1. Überblick über Spring Security

1. Einführung in Spring Security

Spring Security ist ein Sicherheitsframework, das deklarative Sicherheitszugriffskontrolllösungen für Spring-basierte Unternehmensanwendungssysteme bereitstellt. Es stellt eine Reihe von Beans bereit, die im Spring-Anwendungskontext konfiguriert werden können und dabei die Funktionen Spring IoC (Inversion of Control), DI (Dependency Injection) und AOP (Aspect Oriented Programming) vollständig nutzen, um Deklarationen für das Anwendungssystem bereitzustellen Die umfassende Sicherheitszugriffskontrollfunktion reduziert den Aufwand, eine große Menge sich wiederholenden Codes für die Sicherheitskontrolle des Unternehmenssystems zu schreiben.

Spring Security bietet die folgenden Funktionen:

  • Umfassende und skalierbare Unterstützung für Authentifizierung und Autorisierung
  • Schützen Sie sich vor Angriffen wie Sitzungsfixierung, Click-Hijacking, Cross-Site-Request-Forgery usw.
  • Unterstützt die Servlet-API-Integration
  • Unterstützt die Integration mit Spring Web MVC

Die Beziehung zwischen Spring, Spring Boot und Spring Security ist in der folgenden Abbildung dargestellt:

Bitte fügen Sie eine Bildbeschreibung hinzu

2. Schnellstart mit Spring Security

2.1. Einführung von Abhängigkeiten

<!--springboot整合security坐标-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Oder überprüfen Sie es beim Erstellen des Springboot-ProjektsBitte fügen Sie eine Bildbeschreibung hinzu

2.2. Erstellen Sie einen Controller

@RestController
public class HelloController {
    
    
    @GetMapping("hello")
    public String hello(){
    
    
        return "Hello Spring security";
    }
}

2.3. Starten Sie das Projekt

Besuchen Sie: http://localhost:8080/hello. Das Ergebnis ist eine Anmeldeseite. Tatsächlich wurde unsere Anfrage zu diesem Zeitpunkt geschützt. Wenn wir darauf zugreifen möchten, müssen wir uns zuerst anmelden.

Bitte fügen Sie eine Bildbeschreibung hinzu

Spring Security stellt standardmäßig einen Benutzer mit dem Namen user bereit , dessen Passwort in der Konsole zu finden ist.Bitte fügen Sie eine Bildbeschreibung hinzu

4. Konfiguration der Spring Security-Authentifizierung

1、WebSecurityConfigurerAdapter

Natürlich können Sie es auch über eine Konfigurationsklasse konfigurieren, eine zu erbende Konfigurationsklasse erstellen und eine benutzerdefinierte Benutzername- und Kennwortanmeldung implementieren.

/**
 * Spring Security配置类
 * 在springboot2.7 后WebSecurityConfigurerAdapter弃用了,用2.5.4
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        // 对密码进行加密。123 是密码明文,现在 Spring Security 强制性要求『不允许明文存储密码』。
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123");
        auth.inMemoryAuthentication().withUser("tom").password(password).roles("admin");
    }
}

Für Springsecurity ist es zwingend erforderlich, einen Passwortverschlüsseler (PasswordEncoder) zu verwenden, um das ursprüngliche Passwort (Registrierungspasswort) zu verschlüsseln. Daher führt das Vergessen, einen PasswordEncoder anzugeben, There is no PasswordEncoder mapped for the id "null"während der Ausführung zu einer Ausnahme.

Dies liegt daran, dass wir beim Verschlüsseln von Kennwörtern das BCryptPasswordEncoder- Objekt verwenden und Spring Security den Verschlüsseler während des Kennwortvergleichsprozesses nicht selbst „erstellt“. Daher müssen wir den Verschlüsseler im Spring IoC-Container konfigurieren und erstellen. Singleton-Objekt dafür direkt zu verwenden.

Daher müssen wir auch das Singleton-Objekt des Verschlüsselers im Container konfigurieren und erstellen (das Neue oben kann theoretisch in Injektion umgewandelt werden) und die Spring-Sicherheitskonfigurationsklasse ändern

/**
 * Spring Security配置类
 * 在springboot2.7后WebSecurityConfigurerAdapter弃用了,用2.5.4
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        // 对密码进行加密。123 是密码明文,现在 Spring Security 强制性要求『不允许明文存储密码』。
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123");
        //此方法是在代码中写死的,无法从数据库中获取,所以基本不适用
        auth.inMemoryAuthentication().withUser("tom").password(password).roles("admin");
    }
       /**
     * 将PasswordEncoder注入到ioc容器
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
    
    
        return new BCryptPasswordEncoder();
    }
}

Der integrierte Passwort-Encoder von Spring Security umfasst:

Name des Verschlüsselungsalgorithmus PasswortEncoder
NEIN NoOpPasswordEncoder.getInstance()
SHA256 neuer StandardPasswordEncoder()
BCRYPT (offizielle Empfehlung) neuer BCryptPasswordEncoder()
LDAP neuer LdapShaPasswordEncoder()
PBKDF2 neuer Pbkdf2PasswordEncoder()
SKRYPT neuer SCryptPasswordEncoder()
MD4 neuer Md4PasswordEncoder()
MD5 neuer MessageDigestPasswordEncoder („MD5“)
SHA_1 neuer MessageDigestPasswordEncoder („SHA-1“)
SHA_256 neuer MessageDigestPasswordEncoder („SHA-256“)

2. Informationen aus der Datenbank abrufen

  • Abhängigkeiten in POM hinzufügen
 <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- mysql-connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
  • Konfigurieren Sie in yml
server:
  port: 8070
spring:
  # 配置数据源信息
  datasource:
    # 配置数据源类型
    type: com.zaxxer.hikari.HikariDataSource
    # 配置连接数据库信息
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    username: root
    password: 123456
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.woniu.entity
  configuration:
    # 配置MyBatis日志,执行sql的时候,将sql打印到控制台
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • Erstellen Sie unter dem Entitätspaket eine neue Entitätsklasse Users. Es wird empfohlen, User nicht zu verwenden, da es in der UserDetails-Schnittstelle eine Implementierungsklasse namens User gibt, die mehr als einmal zum falschen Paket führt.
package com.woniu.entity;

import lombok.Data;

import java.util.List;
@Data
public class Users {
    
    

   private Integer id;

   private String username;

   private String account;

   private String password;

   private List<String> anths;//该用户拥有的权限

}
  • Erstellen Sie eine neue Tabelle in der Datenbank:
    Bitte fügen Sie eine Bildbeschreibung hinzu
    Benutzertabelle,
    Bitte fügen Sie eine Bildbeschreibung hinzu
    Zuordnungstabelle,
    Bitte fügen Sie eine Bildbeschreibung hinzu
    Berechtigungstabelle
    Bitte fügen Sie eine Bildbeschreibung hinzu
  • Erstellen Sie UsersMapper unter dem Mapper-Paket
package com.woniu.dao;

import com.woniu.entity.Users;

public interface UsersDao {
    
    
        /**
         * 通过账号获取用户信息
         * @param account 
         * @return
         */
        Users getUserInfoByAccount(String account);
}

  • Erstellen Sie unter „Ressourcen“ ein neues Mapper-Paket und erstellen Sie „UsersMapper.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.woniu.mapper.UsersMapper">
    <resultMap id="userMap" type="Users">
        <result column="id" property="id"></result>
        <result column="username" property="username"></result>
        <result column="account" property="account"></result>
        <result column="password" property="password"></result>
        <collection property="anths" ofType="java.lang.String">
            <result column="anth_code"></result>
        </collection>
    </resultMap>
    <select id="getUserInfoByAccount" resultMap="userMap">
        SELECT
            us.id,
            us.username,
            us.account,
            us.password,
            ta.anth_code
        FROM
            t_users us
                left join t_user_anth tua on us.id = tua.user_id
                left join t_anth ta on tua.anth_id = ta.id
        where account = #{account}
    </select>
</mapper>
  • Erstellen Sie unter dem Servicepaket eine MyUserDetailsService-Klasse, um die UserDetailsService-Schnittstelle zu implementieren

    /**
     * spring security认证业务类
     */
    @Service
    public class MyUserDetailsService implements UserDetailsService {
          
          
       
        @Autowired
        private UsersMapper usersMapper;
    
        @Autowired
        private PasswordEncoder passwordEncoder;
        
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          
          
               //调用dao到数据库中根据username查找用户信息
            Users users = usersMapper.getByUserName(username);
            String anths = String.join(",", userInfo.getAnths());
             try {
          
          
                //将查找到的用户帐号与密码保存到Security的User对象中由Security进行比对
                return new User(users.getUsername(), passwordEncoder.encode(users.getPassword()),
                        //配置登录用户有哪些角色和权限,此处模拟直接写死
                        AuthorityUtils.commaSeparatedStringToAuthorityList(anths);
            }catch (Exception e){
          
          
                throw  new UsernameNotFoundException("用户"+username+"不存在");
            }
        }
    }
    
  • Ändern Sie die Spring-Sicherheitskonfigurationsklasse

    
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
          
          
    
        @Autowired
        private MyUserDetailsService userDetailsService;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          
          
           auth.userDetailsService(userDetailsService);
        }
         
        /**
         * 将PasswordEncoder注入到ioc容器
         * @return
         */
        @Bean
        public PasswordEncoder passwordEncoder() {
          
          
            return new BCryptPasswordEncoder();
        }
    }
    
  • Starten Sie das Projekt und testen Sie es im Browser
    Bitte fügen Sie eine Bildbeschreibung hinzu

Supongo que te gusta

Origin blog.csdn.net/lanlan112233/article/details/129737056
Recomendado
Clasificación