[JAVA] Implementierte Authentifizierungsfunktion mit Spring Security ③

** Dies ist eine Fortsetzung von Letztes Mal. ** ** **

** * Wir werden von hier aus viele Dateien erstellen. Wenn Sie einen Fehler machen, , besteht eine hohe Wahrscheinlichkeit, dass Sie nicht zurückkehren können </ font>. Es ist daher eine gute Idee, die Projektinformationen zu kopieren oder auf Github usw. aufzulisten. ** ** ** Ich habe das nicht gemacht und es hat lange gedauert, bis ich das Projekt viele Male erstellt habe. SpringBoot_Di_Security_DB_13.png

5. Implementierung der Spring Security-Authentifizierungsfunktion.

・ Dies ist das Hauptgericht. Wenn die Implementierung bis zum letzten Mal nicht erfolgreich ist, ist die Fehlerbehandlung problematisch. Lassen Sie uns sie daher bis jetzt perfekt implementieren.

Bearbeiten Sie 5-1, POM.

  • Schreiben Sie zunächst die Datei pom.xml neu, in der die Abhängigkeiten von Maven beschrieben werden, um Spring Security einzuführen. Wir werden auch javax.persistence einführen, um die Entitätsklasse zu verwenden, in der die von der Datenbank empfangenen Daten gespeichert sind.

pom.xml



<!-- SpringSecurity -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--Thymeleaf Extension (Sicherheit)-->
<dependency>
	<groupId>org.thymeleaf.extras</groupId>
	<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<!--So verwenden Sie Entitätsanmerkungen-->
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>javax.persistence-api</artifactId>
    <version>2.2</version>
</dependency>
<!-- JpaRepository-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

・ ** Wenn Sie nur den Code schreiben, wird er nicht wiedergegeben. ** Das Maven-Projekt muss aktualisiert werden.

"Klicken Sie mit der rechten Maustaste auf das Projekt" -> "Maven" -> "Projekt aktualisieren", um die Maven-Datei zu aktualisieren. Wenn die ausgewählte Datei korrekt ist, klicken Sie auf "OK", um sie zu aktualisieren.

-Wenn beim Ausführen der App kein Fehler auf der Konsole auftritt, ist dies in Ordnung.

5-2, Implementieren Sie die Authentifizierungsfunktion.

·Es ist das Ende. Schließlich werden wir viele Dateien erstellen. Das Dateistrukturbild ist wie folgt. ** Roter Rahmen ist neu </ font>, Gelber Rahmen ist eine zu bearbeitende Datei </ font>. ** ** **

SpringBoot_Di_Security_DB_13.png

-Auch ich habe ein Bild des Verarbeitungsablaufs gemacht, also beziehen Sie sich bitte darauf. (Es tut mir leid, dass es sehr schwer zu sehen ist ...)

SpringBoot_Di_Security_DB_14.png

・ Geben Sie den Code ein. Ich habe viele Kommentare geschrieben, aber ehrlich gesagt ist es schwer, alles zu verstehen und es kann falsch sein. Wir hoffen, dass Sie Ihr Verständnis untersuchen und vertiefen.

java:SpringLogin.app.config/WebSecurityConfig.java



package SpringLogin.app.config;

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.builders.WebSecurity;
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 SpringLogin.app.service.UserDetailsServiceImpl;

/**
 *Festlegen der Klasse für die Verwendung von Spring Security
 *Legen Sie Parameter für die Anmeldeverarbeitung, Datenzugriffsziele für Bildschirmübergänge und die Authentifizierungsverarbeitung fest
 * @author aoi
 *
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	//Instanziieren Sie die Methode von UserDetailsServiceImpl, damit sie verwendet werden kann.
	@Autowired
	private UserDetailsServiceImpl userDetailsService;
	
	//Da das von der Datenbank erhaltene Kennwort, das mit dem Formularwert verglichen werden soll, verschlüsselt ist, wird es auch zum Verschlüsseln des Formularwerts verwendet.
	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
		return bCryptPasswordEncoder;
	}
	
	/**
	 *Legen Sie eine Anforderung fest, um Autorisierungseinstellungen zu ignorieren
	 *Statische Ressourcen(image,javascript,css)Vom Autorisierungsprozess ausschließen
	 */
	@Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                            "/images/**",
                            "/css/**",
                            "/javascript/**"
                            );
    }
	
	/**
	 *Legen Sie die Authentifizierungs- / Autorisierungsinformationen fest
	 *Legen Sie den Wert des Attributs name fest, um die URL und die Parameter des Bildschirmübergangs abzurufen
	 *Überschreiben der Spring Security-Konfigurationsmethode.
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
		    .authorizeRequests()
		        .anyRequest().authenticated()
		        .and()
		    .formLogin()
		        .loginPage("/login") //Da die Anmeldeseite nicht über den Controller geleitet wird, muss sie mit ViewName verknüpft werden.
		        .loginProcessingUrl("/login") //Senden Sie die URL des Formulars. Der Authentifizierungsprozess wird ausgeführt, wenn eine Anforderung an diese URL gesendet wird
		        .usernameParameter("username") //Explizites Namensattribut des Anforderungsparameters
		        .passwordParameter("password")
		        .defaultSuccessUrl("/userList", true) //URL, zu der bei erfolgreicher Authentifizierung gewechselt werden soll
		        .failureUrl("/login?error") //URL, zu der übergegangen werden soll, wenn die Authentifizierung fehlschlägt
		        .permitAll() //Jeder Benutzer kann eine Verbindung herstellen.
		        .and()
		    .logout()
		        .logoutUrl("/logout")
		        .logoutSuccessUrl("/login?logout")
		        .permitAll();
	}
	
	/**
	 *Einstellungsmethode, die die während der Authentifizierung verwendete Datenquelle definiert
	 *Hier werden die von der Datenbank erfassten Benutzerinformationen im userDetailsService als Vergleichsinformationen zum Zeitpunkt der Authentifizierung festgelegt.
	 * @param auth
	 * @throws Exception
	 *AuthenticationManagerBuilder verfügt über Authentifizierungsfunktionen.
	 *Der userDetailsService ist einer von ihnen, um festzustellen, ob der im Formular eingegebene Benutzer verfügbar ist.
	 * https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.html
	 */
	@Autowired
	public void configure(AuthenticationManagerBuilder auth) throws Exception{
		auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
		/*
		 *Verwenden Sie für In-Memory:
		auth
		    .inMemoryAuthentication()
		        .withUser("user").password("{noop}password").roles("USER");
		*/
	}

}


java:SpringLogin.app.servise/UserDetailsServiceImpl.java



package SpringLogin.app.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import SpringLogin.app.repository.LoginUserDao;
import SpringLogin.app.entity.LoginUser;

/**
 *Spring Security Service-Implementierungsklasse für die Benutzersuche
 *DB kann zur Authentifizierung verwendet werden, indem es als Argument von DataSource angegeben wird
 * @author aoi
 *
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService{
	
	//Eine Klasse, die eine Methode zum Suchen von Benutzerinformationen aus der Datenbank implementiert
	@Autowired
	private LoginUserDao userDao;
	
	/**
	 *Implementierungsmethode der UserDetailsService-Schnittstelle
	 *Wenn die Datenbank nach dem aus dem Formular erhaltenen Benutzernamen durchsucht wird und ein übereinstimmender vorhanden ist,
	 *Erstellen Sie ein UserDetails-Objekt mit Kennwort- und Berechtigungsinformationen
	 *Treffen Sie eine Anmeldeentscheidung, indem Sie den obigen Eingabewert mit dem Kennwort vergleichen, das Sie von der Datenbank in der Konfigurationsklasse erhalten haben.
	 */
	@Override
	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

		LoginUser user = userDao.findUser(userName);
		
		if (user == null) {
			throw new UsernameNotFoundException("User" + userName + "was not found in the database");
		}
		//Liste der Berechtigungen
		//Es gibt Admin, User usw., aber da wir sie diesmal nicht verwenden, wird nur USER vorübergehend eingestellt.
		//Um Berechtigungen verwenden zu können, müssen Berechtigungstabellen und Benutzerberechtigungstabellen in der Datenbank erstellt und verwaltet werden.
		
		List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
		GrantedAuthority authority = new SimpleGrantedAuthority("USER");

		grantList.add(authority);
		
		//Das RawData-Passwort kann nicht übergeben werden, daher Verschlüsselung
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        //Da UserDetails eine Schnittstelle ist, wandeln Sie das vom Konstruktor der User-Klasse erstellte Benutzerobjekt um.
		UserDetails userDetails = (UserDetails)new User(user.getUserName(), encoder.encode(user.getPassword()),grantList);
		
		return userDetails;
	}

}


java:SpringLogin.app.repository/LoginUserDao.java



package SpringLogin.app.repository;

import javax.persistence.EntityManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import SpringLogin.app.entity.LoginUser;

/**
 *Dao ruft die Zugriffsmethode auf DB auf
 * @author aoi
 *
 */
@Repository
public class LoginUserDao {
	
	/**
	 *Ein Objekt, das eine Entität verwaltet.
	 *Das erforderliche Objekt, das mit der folgenden Methode in die Entitätsklasse LoginUser umgewandelt und der Rückgabewert zurückgegeben werden soll.
	 */
	@Autowired
	EntityManager em;
	
	/**
	 *Die Suche nach dem entsprechenden Benutzer aus dem Eingabewert des Formulars Null wird zurückgegeben, wenn keine Übereinstimmung vorliegt
	 * @param userName
	 * @return Wenn es einen passenden Benutzer gibt:UserEntity, wenn es nicht existiert:Null
	 */
	public LoginUser findUser(String userName) {

		String query = "";
		query += "SELECT * ";
		query += "FROM user ";
		query += "WHERE user_name = :userName "; //Verwenden Sie NamedParameter, damit Sie den Wert des Arguments mit setParameter zuweisen können
		
		//Da das von EntityManager erhaltene Ergebnis ein Objekt ist, muss es in den LoginUser-Typ umgewandelt werden.
		return (LoginUser)em.createNativeQuery(query, LoginUser.class).setParameter("userName", userName).getSingleResult();
	}

}


java:SpringLogin.app.entity/LoginUser.java



package SpringLogin.app.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 *Entität zum Speichern des Benutzernamens und des Passworts des angemeldeten Benutzers
 * @author aoi
 *
 */
@Entity
@Table(name = "user")
public class LoginUser {
	
	@Column(name = "user_id")
	@Id
	private Long userId;
	
	@Column(name = "user_name")
	private String userName;
	
	@Column(name = "password")
	private String password;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}


java:SpringLogin.app.repository/UserRepository.java



package SpringLogin.app.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import SpringLogin.app.entity.LoginUser;

/*
 *Ein Mechanismus zum Suchen von Daten im Spring Framework.
 *Die Datensuche wird durch Registrierung in DI möglich. Das Argument ist <Entitätsklasse,Werden Sie ein ID-Typ>
 * https://www.tuyano.com/index3?id=12626003
 */
@Repository
public interface UserRepository extends JpaRepository<LoginUser, Integer>{

}


java:SpringLogin.app.config/SpringLoginApplication.java



package SpringLogin.app.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication //Zeigt an, dass es sich um eine Spring Boot-Anwendung handelt
@ComponentScan("SpringLogin.app") //Registrieren Sie sich bei DI als Bohne. Kann als Paket angegeben werden.
@EntityScan("SpringLogin.app.entity") //Registriert in DI als Bohne wie oben.
@EnableJpaRepositories("SpringLogin.app.repository") //Zum Aktivieren des Jpa-Repositorys. Suchen Sie innerhalb des angegebenen Pakets und@Registrieren Sie die Klasse bei Repository als Bean.
public class SpringLoginApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringLoginApplication.class, args);
	}

}

· Ist Prost für gute Arbeit. Es ist ein langer Code, aber noch einen Schritt weiter! Nachdem Sie den Code bisher geschrieben haben, überprüfen Sie ihn in Ihrem Browser.

5-3, Funktionsprüfung.

Erster Zugriff hier → http: // localhost: 8080 / Dann wechselt die URL zum / login-Bildschirm. Dies ist ein Beweis dafür, dass Spring Security angewendet wurde, und geben Sie in der authorizeRequests-Methode von WebSecurityConfig.java eine URL an, auf die zugegriffen werden kann, auch wenn Sie nicht angemeldet sind. Da diesmal jedoch nichts angegeben ist, können Sie nur dann auf die Anmeldeseite zugreifen, wenn Sie nicht angemeldet sind. Wenn Sie also auf localhost: 8080 / zugreifen, werden Sie zu / login weitergeleitet.

SpringBoot_Di_Security_DB_15.gif

・ Es ist in Ordnung, wenn es wie im obigen Bild funktioniert.

-Nächste überprüfen Sie die Authentifizierungsfunktion.

Melden Sie sich zuerst mit dem falschen Pfad und Benutzer an. Dann kann ich mich nicht anmelden und werde zu "/ login? Error" weitergeleitet. Dies wird durch failUrl () in WebSecurityConfig.jav beeinflusst.

SpringBoot_Di_Security_DB_16.gif

・ Es ist in Ordnung, wenn es wie im obigen Bild funktioniert.

Melden Sie sich dann mit einem legitimen Benutzer an und übergeben Sie. Dieses Mal wurden zwei Benutzer (Benutzer1, Pass1 +) (Yama, Kawa) erstellt, aber einer von beiden ist in Ordnung.

SpringBoot_Di_Security_DB_17.gif

・ Es ist in Ordnung, wenn es wie im obigen Bild funktioniert.

Zusammenfassung

Das ist es. Vielen Dank für Ihre lange Beziehung. Ich hoffe, Sie haben irgendwie verstanden, wie man die Authentifizierungsfunktion und MySQL verwendet. Ich habe es noch nicht vollständig verstanden. Wenn Sie also etwas falsch finden oder vermissen, kommentieren Sie bitte: bow:

Als Eindruck, ehrlich gesagt, stieg Rails, also leckte ich es ein wenig. Das liegt daran, dass Rails ein Gerät hatte, sodass ich die Anmeldefunktion nicht schwer implementieren konnte. Spring Security war um eine Größenordnung schwieriger ... Ich habe nach verschiedenen Artikeln gesucht, aber gibt es jemanden, der das wirklich versteht und zusammenfasst? Ich fühle, dass. Ich war diesmal nicht in der Lage, etwas zu veröffentlichen, ohne es zu verstehen, aber ich wollte es so schnell wie möglich für Menschen veröffentlichen, die wie ich leiden, also habe ich es in diesem Zustand veröffentlicht! Ich habe noch viel zu tun, deshalb möchte ich meine Fähigkeiten verbessern! Vielen Dank.

Recommended Posts