[JAVA] Spring 5 MVC-Webanwendungsentwicklung mit Visual Studio Code Spring Security-Nutzung 1/3 [Vorbereitung]

Einführung

Wir werden das in SQL Server Connection erstellte Projekt erweitern. Wenn Sie der Reihe nach kopieren und einfügen, haben Sie vorerst ein sich bewegendes Objekt. Ich war besonders über die Reihenfolge, in der beim Kopieren kein Fehler aufgetreten ist. Existiert dieser Code zu diesem Zeitpunkt? Brauchst du es? Es gibt auch einen Teil namens. Der Fehlerprüfungsprozess ist unvollständig. Bitte seien Sie gewarnt.

Erstellt mit den folgenden Spezifikationen.

Umgebung

OS:Windows 10 Pro 64bit DB:SQL Server 2019(Cent OS 8 on Hyper-V) Editor:Visual Studio Code 1.44.2 JDK:AdoptOpenJDK 11.0.6+10 x64 Apache Maven:v3.6.3 Apache Tomcat:v9.0.31

Erstellungsverfahren

  1. Erstellen Sie eine Tabelle zum Speichern von Benutzerinformationen
  2. Erstellung einer Entität und eines Repositorys, die für den DB-Zugriff erforderlich sind
  3. Einstellungen für die Verwendung von Spring Security
  4. Erstellen Sie eine Registrierungsseite für Administratoren
  5. Erstellen einer allgemeinen Benutzerregistrierungsseite

Erstellen Sie eine Tabelle zum Speichern von Benutzerinformationen

Erstellen Sie eine UserInfo-Tabelle zum Speichern von Benutzerinformationen und eine UserRoles-Tabelle zum Speichern von Rollen in der in [hier] erstellten Datenbank (https://qiita.com/t_skri/items/8d69c423042e310434d0).

UserInfo


CREATE TABLE [dbo].[UserInfo](
	[UserId] [varchar](255) NOT NULL,
	[Password] [varchar](255) NOT NULL,
	[UserNameJP] [nvarchar](255) NOT NULL,
	[SectionNameJP] [nvarchar](255) NOT NULL,
	[Enabled] [bit] NOT NULL,
 CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED 
(
	[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY];

UserRoles


CREATE TABLE [dbo].[UserRoles](
	[UserId] [varchar](255) NOT NULL,
	[Authority] [varchar](255) NOT NULL,
 CONSTRAINT [PK_UserRoles] PRIMARY KEY CLUSTERED 
(
	[UserId] ASC,
	[Authority] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY];

Projekterstellung

Ich habe das in SQL Server Connection erstellte Projekt nach "D: \ JAVA \ Project \ securitySample" kopiert und erstellt.

pom.xml Fügen Sie das für Spring Security erforderliche Repository und das Repository hinzu, mit dem die Anzahl der Zeichen im Kennwort überprüft wird.

<properties>
	<spring-security.version>5.3.0.RELEASE</spring-security.version>
</properties>

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-web</artifactId>
	<version>${spring-security.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-config</artifactId>
	<version>${spring-security.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-taglibs</artifactId>
	<version>${spring-security.version}</version>
</dependency>

<dependency>
   	<groupId>org.hibernate.validator</groupId>
    	<artifactId>hibernate-validator</artifactId>
    	<version>6.1.2.Final</version>
    	<scope>compile</scope>
</dependency>

Die gesamte pom.xml.

pom.xml


<?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.example</groupId>
	<artifactId>securitySample1</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>war</packaging>
 
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
		<spring.version>5.2.4.RELEASE</spring.version>
		<spring-security.version>5.3.0.RELEASE</spring-security.version>
        <!-- web.Führen Sie build auch ohne XML aus-->
        <failOnMissingWebXml>false</failOnMissingWebXml>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
			<scope>compile</scope>
		</dependency>

		<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-context-support</artifactId>
    		<version>${spring.version}</version>
    		<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
			<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring-security.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring-security.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-taglibs</artifactId>
			<version>${spring-security.version}</version>
		</dependency>

		<dependency>
    		<groupId>com.microsoft.sqlserver</groupId>
    		<artifactId>mssql-jdbc</artifactId>
    		<version>8.2.1.jre11</version>
    		<scope>runtime</scope>
		</dependency>

		<dependency>
		    <groupId>com.zaxxer</groupId>
		    <artifactId>HikariCP</artifactId>
		    <version>3.4.2</version>
		    <scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf-spring5</artifactId>
			<version>3.0.11.RELEASE</version>
			<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-java8time</artifactId>
			<version>3.0.4.RELEASE</version>
			<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
	    	<groupId>org.hibernate.validator</groupId>
	    	<artifactId>hibernate-validator</artifactId>
	    	<version>6.1.2.Final</version>
	    	<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.10</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
</project>

Entitätserstellung

Erstellen Sie eine Entität zum Speichern von Benutzerinformationen.

D:\JAVA\Project\securitySample\src\main\java\com\example\persistence
└─entity
  ├─UserInfo.java
  └─UserRoles.java

UserRoles.java Speichert Rollen (Berechtigungen).

UserRoles.java


package com.example.persistence.entity;

import lombok.Data;

@Data
public class UserRoles {
	private String userId;
	private String authority;

	public UserRoles() {}

	public UserRoles(String userId, String authority) {
		this.userId = userId;
		this.authority = authority;
	}

}

UserInfo.java Speichert Benutzerinformationen.

UserInfo.java


package com.example.persistence.entity;

import java.util.List;

import lombok.Data;

@Data
public class UserInfo {
    private String userId;
	private String password;
	private String userNameJP;
	private String sectionNameJP;
	private Boolean enabled;
	private List<UserRoles> userRolesList;

	public UserInfo() {}

	public UserInfo(String userId, String userNameJP, String sectionNameJP, Boolean enabled) {
		this.userId = userId;
		this.userNameJP = userNameJP;
		this.sectionNameJP = sectionNameJP;
		this.enabled = enabled;
	}
}

Repository erstellen

Erstellen Sie ein Repository für den Zugriff auf die Datenbank.

D:\JAVA\Project\securitySample\src\main\java\com\example\persistence
└─repository
  ├─UserInfoRepository.java
  ├─UserInfoRepositoryImpl.java
  ├─UserRolesRepository.java
  └─UserRolesRepositoryImpl.java

UserInfoRepository.java

UserInfoRepository.java


package com.example.persistence.repository;

import java.util.List;
import java.util.Optional;

import com.example.persistence.entity.UserInfo;

public interface UserInfoRepository {
    Optional<UserInfo> selectDetailByUserId(String id);

	Integer insert(UserInfo userInfo);

	Integer update(UserInfo userInfo);

	Integer delete(String userId);

	List<UserInfo> findUserAll();
}

UserInfoRepositoryImpl.java

UserInfoRepositoryImpl.java


package com.example.persistence.repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.persistence.entity.UserInfo;
import com.example.persistence.entity.UserRoles;

@Repository
public class UserInfoRepositoryImpl implements UserInfoRepository{
    @Autowired
    NamedParameterJdbcTemplate jdbcTemplate;

    private static final RowMapper<UserInfo> INFO_MAPPER = (rs, rowNum) ->
    new UserInfo(rs.getString("UserId"),
            rs.getString("UserNameJP"),
            rs.getString("SectionNameJP"),
            rs.getBoolean("Enabled")
            );

    private static final RowMapper<UserRoles> ROLES_MAPPER = (rs, rowNum) ->
    new UserRoles(rs.getString("UserId"),
            rs.getString("Authority")
            );

    @Override
    public Optional<UserInfo> selectDetailByUserId(String id) {
        try {

            UserInfo userInfo = new UserInfo();
            List<UserRoles> userRolesList = new ArrayList<UserRoles>();

            String sql = "SELECT UserInfo.UserId, UserInfo.Password, UserInfo.UserNameJP, UserInfo.SectionNameJP, UserInfo.Enabled"
                    + " , UserRoles.Authority"
                    + " FROM UserInfo INNER JOIN UserRoles ON UserInfo.UserId = UserRoles.UserId "
                    + " WHERE (UserInfo.UserId = :id)";

            MapSqlParameterSource parameterSource = new MapSqlParameterSource();
            parameterSource.addValue("id", id);
            List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql, parameterSource);

            for(Map<String, Object> result : resultList) {
                UserRoles userRoles = new UserRoles();
                userRoles.setUserId((String) result.get("UserId"));
                userRoles.setAuthority((String) result.get("Authority"));
                userRolesList.add(userRoles);

                userInfo.setUserId((String) result.get("UserId"));
                userInfo.setPassword((String) result.get("Password"));
                userInfo.setUserNameJP((String) result.get("UserNameJP"));
                userInfo.setSectionNameJP((String) result.get("SectionNameJP"));
                userInfo.setEnabled((Boolean) result.get("Enabled"));
            }

            userInfo.setUserRolesList(userRolesList);

            return Optional.of(userInfo);

        }catch (EmptyResultDataAccessException e) {

            return Optional.empty();
        }
    }

    @Override
    public Integer insert(UserInfo userInfo) {
        String sql = "INSERT INTO UserInfo"
                + " VALUES(:UserId, :Password, :UserNameJP, :SectionNameJP, :Enabled);";
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId",          userInfo.getUserId());
        parameterSource.addValue("Password",        userInfo.getPassword());
        parameterSource.addValue("UserNameJP",      userInfo.getUserNameJP());
        parameterSource.addValue("SectionNameJP",   userInfo.getSectionNameJP());
        parameterSource.addValue("Enabled",         userInfo.getEnabled());

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public Integer update(UserInfo userInfo) {
        String sql = "UPDATE UserInfo SET "
                + " Password = :Password "
                + ",UserNameJP = :UserNameJP "
                + ",SectionNameJP = :SectionNameJP "
                + ",Enabled = :Enabled "
                + " WHERE UserId = :UserId;";

        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId",          userInfo.getUserId());
        parameterSource.addValue("Password",        userInfo.getPassword());
        parameterSource.addValue("UserNameJP",      userInfo.getUserNameJP());
        parameterSource.addValue("SectionNameJP",   userInfo.getSectionNameJP());
        parameterSource.addValue("Enabled",         userInfo.getEnabled());

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public Integer delete(String userId) {
        String sql = "DELETE FROM UserInfo WHERE UserId = :UserId;";
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId", userId);

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public List<UserInfo> findUserAll() {
        String sql1 = "SELECT DISTINCT UserInfo.UserId, UserInfo.UserNameJP, UserInfo.SectionNameJP, UserInfo.Enabled"
                + " FROM UserInfo INNER JOIN UserRoles ON UserInfo.UserId = UserRoles.UserId "
                + " WHERE UserRoles.Authority = 'ROLE_USER'"
                + " ORDER BY UserInfo.UserId;" ;

        List<UserInfo> userInfoList = jdbcTemplate.query(sql1, INFO_MAPPER);

        userInfoList.forEach(userInfo -> {
            String sql2 = "SELECT * FROM UserRoles WHERE UserId = :UserId;";
            MapSqlParameterSource parameterSource = new MapSqlParameterSource();
            parameterSource.addValue("UserId", userInfo.getUserId());
            List<UserRoles> userRolesList = jdbcTemplate.query(sql2, parameterSource, ROLES_MAPPER);

            userInfo.setUserRolesList(userRolesList);
        });

        return userInfoList;
    }
}

UserRolesRepository.java

UserRolesRepository.java


package com.example.persistence.repository;

import com.example.persistence.entity.UserRoles;

public interface UserRolesRepository {
	Integer insert(UserRoles userRoles);

	Integer update(UserRoles userRoles);

	Integer delete(String userId);

	Integer adminCheck();
}

UserRolesRepositoryImpl.java

UserRolesRepositoryImpl.java


package com.example.persistence.repository;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.persistence.entity.UserRoles;

@Repository
public class UserRolesRepositoryImpl implements UserRolesRepository {
    @Autowired
    NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public Integer insert(UserRoles userRoles) {
        String sql = "INSERT INTO UserRoles"
                + " VALUES(:UserId, :Authority);";
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId", userRoles.getUserId());
        parameterSource.addValue("Authority", userRoles.getAuthority());

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public Integer update(UserRoles userRoles) {
        String sql = "UPDATE UserRoles SET Authority = :Authority"
                + " WHERE UserId = :UserId;";
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId", userRoles.getUserId());
        parameterSource.addValue("Authority", userRoles.getAuthority());

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public Integer delete(String userId) {
        String sql = "DELETE FROM UserRoles WHERE UserId = :UserId;";
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("UserId", userId);

        Integer rows = jdbcTemplate.update(sql, parameterSource);
        return rows;
    }

    @Override
    public Integer adminCheck() {
        Integer rows = 0;

        String sql = "SELECT COUNT(*) AS CNT"
                + " FROM UserRoles"
                + " WHERE Authority = 'ROLE_ADMIN';" ;
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();

        Map<String, Object> result = jdbcTemplate.queryForMap(sql,parameterSource);
        rows = Integer.parseInt(result.get("CNT").toString());

        return rows;
    }
}

Erstellung der Sicherheitsabteilung

Erstellen Sie einen "Sicherheits" -Ordner unter "D: \ JAVA \ Project \ sqlSample \ src \ main \ java \ com \ example". Erstellen Sie einen Konfigurationsordner direkt darunter. Erstellen Sie die folgenden Dateien im Konfigurationsordner.

Erstellen Sie die folgenden Dateien direkt unter dem Sicherheitsordner.

D:\JAVA\Project\securitySample\src\main\java\com\example\security
├─config
|  ├─SecurityConfig.java
|  └─SpringSecurityInitializer.java
├─MyAccessDeniedHandler.java
├─MyAuthenticationSuccessHandler.java
├─MyUserDetails.java
└─MyUserDetailsService.java

MyAuthenticationSuccessHandler.java Geben Sie die Seite an, die angezeigt werden soll, wenn die Authentifizierung erfolgreich ist. Es ist auch möglich, durch Rolle zu teilen.

MyAuthenticationSuccessHandler.java


package com.example.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;


public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler  {
	@Override
    public void onAuthenticationSuccess(
        HttpServletRequest request, HttpServletResponse response, Authentication authentication)
        		throws IOException, ServletException {

        RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

        //Ziel nach Authentifizierung umleiten
        if (authentication.getAuthorities().toString().contains("ADMIN")) {
            //Die ADMIN-Rolle zeigt die Benutzerregistrierungsseite an.
        	redirectStrategy.sendRedirect(request, response, "/userReg/index");
        } else {
            //Die Seite, die für andere Rollen angezeigt werden soll.
        	redirectStrategy.sendRedirect(request, response, "/hello/index");
        }
    }
}

MyAccessDeniedHandler.java Geben Sie die Seite an, die angezeigt werden soll, wenn bei der Authentifizierung ein Fehler auftritt.

MyAccessDeniedHandler.java


package com.example.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.access.AccessDeniedHandler;

public class MyAccessDeniedHandler implements AccessDeniedHandler{
	@Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);

        RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
        redirectStrategy.sendRedirect(request, response, "/auth/403");
    }
}

MyUserDetails.java Fügen Sie die Elemente hinzu, die Sie zu den Standardanmeldeinformationen hinzufügen möchten. Das japanische Element des Benutzernamens und des Abteilungsnamens werden hinzugefügt.

MyUserDetails.java


package com.example.security;

import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import com.example.persistence.entity.UserInfo;

public class MyUserDetails extends User {
    private static final long serialVersionUID = 1L;
    private final String userNameJP;
	private final String sectionNameJP;

	public MyUserDetails(UserInfo userInfo, List<? extends GrantedAuthority> authorityList) {
		super(userInfo.getUserId(), userInfo.getPassword(), userInfo.getEnabled(), true, true, true, authorityList);
		this.userNameJP = userInfo.getUserNameJP();
		this.sectionNameJP = userInfo.getSectionNameJP();
	}

	public String getUserNameJP() {
		return userNameJP;
	}

	public String getSectionNameJP() {
		return sectionNameJP;
	}
}

MyUserDetailsService.java

MyUserDetailsService.java


package com.example.security;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.example.persistence.entity.UserInfo;
import com.example.persistence.entity.UserRoles;
import com.example.persistence.repository.UserInfoRepository;

public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    UserInfoRepository userInfoRepository;

    @Override
    public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
        Optional<UserInfo> userInfoOpt = userInfoRepository.selectDetailByUserId(userId);
        if (userInfoOpt == null) {
            throw new UsernameNotFoundException("");
        }

        UserInfo userInfo = userInfoOpt.get();

        List<SimpleGrantedAuthority> authorityList = new ArrayList<SimpleGrantedAuthority>();

        List<UserRoles> roles = userInfo.getUserRolesList();
        for (UserRoles role: roles) {
            authorityList.add(new SimpleGrantedAuthority(role.getAuthority()));
        }

        return new MyUserDetails(userInfo, authorityList);
    }
}

SecurityConfig.java Die Standardauthentifizierung wird in dieser Anwendung nicht verwendet, sie wird jedoch als Beispiel für die Verwendung zusammen mit der Formularauthentifizierung beschrieben. In der Beschreibung wird der Standardauthentifizierung Vorrang eingeräumt.

SecurityConfig.java


package com.example.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
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;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.filter.CharacterEncodingFilter;

import com.example.security.MyAccessDeniedHandler;
import com.example.security.MyAuthenticationSuccessHandler;
import com.example.security.MyUserDetailsService;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(myUserDetailsService());
	}

	@Bean
	public UserDetailsService myUserDetailsService() {
		return new MyUserDetailsService();
	}

	@Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
	/**
	 *Grundlegende Authentifizierung
	 */
	@Configuration
	@Order(Ordered.HIGHEST_PRECEDENCE)
	public class WebSecurityBasicConfig extends WebSecurityConfigurerAdapter {

		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http
				.csrf().disable()
				.antMatcher("/api/**")
				.authorizeRequests()
					.antMatchers("/api/admin/**").hasAnyRole("ADMIN")
				.anyRequest().authenticated()
					.and()
					.httpBasic()
            ;
		}
	}

	/**
	 *Formularauthentifizierung
	 */
	@Configuration
	public class WebSecurityFormConfig extends WebSecurityConfigurerAdapter {

		@Override
		protected void configure(HttpSecurity http) throws Exception {
			CharacterEncodingFilter filter = new CharacterEncodingFilter();
	        filter.setEncoding("UTF-8");
	        filter.setForceEncoding(true);

			  http
			  	.addFilterBefore(filter, CsrfFilter.class)
			  	.authorizeRequests()

			  	//Zugänglich für jede Rolle
		  		.antMatchers("/", "/resources/**", "/webjars/**", "/auth/**", "/adminReg/**").permitAll()

		  		//Zugriffseinstellungen für Rollen
		  		// '/userReg/'URLs, die mit beginnen'ADMIN'Es kann nur auf Rollen zugegriffen werden
			    .antMatchers("/userReg/**").hasRole("ADMIN")

			  	.anyRequest().authenticated()
			  	.and()
			  		.formLogin()
			  		.loginProcessingUrl("/login")
			  		.loginPage("/auth/login")
			  		.failureUrl("/auth/login-error")
			  		.successHandler(new MyAuthenticationSuccessHandler())
			  		.permitAll()
		        .and()
		        //Einstellungen für die Abmeldeverarbeitung
		        	.logout()
		            //URL des Abmeldevorgangs
		            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
		            //Übergangsziel-URL bei erfolgreicher Abmeldung
		            .logoutSuccessUrl("/auth/login")
		            //Cookie-Name, der beim Abmelden gelöscht werden soll
		            .deleteCookies("JSESSIONID")
		            //Aktivieren Sie die Sitzungszerstörung beim Abmelden
		            .invalidateHttpSession(true)
		            .permitAll()
		        .and()
		        //403 Einstellung des Übergangsziels zum Zeitpunkt des Fehlers
		        	.exceptionHandling()
		        	.accessDeniedHandler(new MyAccessDeniedHandler())

		        ;
		}

	}
}

SpringSecurityInitializer.java

SpringSecurityInitializer.java


package com.example.security.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

}

WebAppInitializer.java hinzugefügt

Fügen Sie SecurityConfig.class zu getRootConfigClasses von WebAppInitializer hinzu.

protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] {SecurityConfig.class, PersistenceConfig.class, ServiceConfig.class};
}

Die gesamte WebAppInitializer.java.

WebAppInitializer.java


package com.example.web.config;

import java.nio.charset.StandardCharsets;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.example.persistence.config.PersistenceConfig;
import com.example.security.config.SecurityConfig;
import com.example.service.config.ServiceConfig;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     *Gibt Java Config-Klassen für Nicht-Spring-MVC an, z. B. Geschäftslogik.
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {SecurityConfig.class, PersistenceConfig.class, ServiceConfig.class};
    }

    /**
     *Gibt die Java Config-Klasse für Spring MVC an.
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {MvcConfig.class};
    }

    /**
     *Geben Sie das URL-Muster für DispatcherServlet an.
     * "/"Durch Angabe empfängt DispatcherServlet alle Anforderungen.
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     *Geben Sie den Servlet-Filter an.
     *Wenn mehrere Filter vorhanden sind, werden sie in der im Array angegebenen Reihenfolge ausgeführt.
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] {
                new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)
            };
    }
}

Zusammenfassung

Damit sind die erforderlichen Vorbereitungen für die Verwendung von Spring Security abgeschlossen. Als Nächstes erstellen wir eine Anmeldeseite und eine Seite zur Erstellung von Verwaltungsbenutzern.

Recommended Posts

Spring 5 MVC-Webanwendungsentwicklung mit Visual Studio Code Spring Security-Nutzung 1/3 [Vorbereitung]
Spring 5 MVC-Webanwendungsentwicklung mit Visual Studio Code Spring Security-Verwendung 2/3 [Seitenerstellung 1/2]
Spring 5 MVC-Webanwendungsentwicklung mit Visual Studio Code Spring Security-Verwendung 3/3 [Seitenerstellung 2/2]
Spring5 MVC-Webanwendungsentwicklung mit Visual Studio Code SQL Server-Verbindung
Entwicklung von Spring5 MVC-Webanwendungen mit Visual Studio Code Maven-Vorlagenerstellung
Spring5 MVC-Webanwendungsentwicklung mit Visual Studio-Code Hello World Creation
Spring Boot2-Webanwendungsentwicklung mit Visual Studio Code SQL Server-Verbindung
Spring Boot2-Webanwendungsentwicklung mit Visual Studio Code Hello World-Erstellung
Entwicklung von Spring5 MVC-Webanwendungen mit Visual Studio Code Environment-Konstruktion (Installation von JDK11 / Maven / Tomcat / Visual Studio Code)
Erstellen Sie mit Java + Spring eine Web-APP-Entwicklungsumgebung mit Visual Studio Code
Starten Sie die Entwicklung von Webanwendungen mit Spring Boot
Verwendungshinweis zu Spring Security: Zusammenarbeit mit Spring MVC und Boot
Erstellen Sie eine Java-Programmentwicklungsumgebung mit Visual Studio Code
Erstellung einer Java-Webanwendungsentwicklungsumgebung mit VS-Code (struts2)
Verwenden Sie PlantUML mit Visual Studio Code
Führen Sie die WEB-Anwendung mit Spring Boot + Thymeleaf aus
Eine Aufzeichnung zum Einrichten einer Java-Entwicklungsumgebung mit Visual Studio Code
Erleben Sie .NET 5 mit Docker und Visual Studio Code
Erste Schritte mit Java-Programmen mit Visual Studio Code
Warum können Sie Java mit Visual Studio Code entwickeln?
Etwa der Ablauf der Entwicklung von Webanwendungen mit Rails.
Vorbereitung der Android-App-Entwicklung 7/15
Memo zur Entwicklung von Webanwendungen mit MVN, Tomcat, JSP / Servlet mit VScode
Die erste WEB-Anwendung mit Spring Boot-Making a Pomodoro Timer-
So erhalten Sie eine leere Anfrage mit Spring Web MVC @RequestBody
Java-Konfiguration mit Spring MVC
Spring Security-Nutzungsnotiz CSRF
Spring Security-Nutzungsnotiz Run-As
[Spring Boot] Erstellung von Webanwendungen
Sicherheit der Verwendungsnotizmethode für Spring Security
Spring Security-Nutzungsnotiz Remember-Me
Zusammenfassung des Artikels zur Entwicklung von Webanwendungen
Anmeldefunktion mit Spring Security
Java mit Visual Studio Code
Mit Docker erstellte Webanwendung (1)
Spring Security-Nutzungsnotiz CORS
Spring Security-Verwendungsnotiztest
Vergleich der WEB-Anwendungsentwicklung mit Rails und Java Servlet + JSP
Verwendung von PlantUML mit Visual Studio Code (erstellt am 30. Oktober 2020)
Erstellen wir eine Buchverwaltungs-Webanwendung mit Spring Boot part1
Lassen Sie uns mit Spring Boot part3 eine Webanwendung für die Buchverwaltung erstellen
Lassen Sie uns mit Spring Boot part2 eine Webanwendung für die Buchverwaltung erstellen
[Wahrscheinlich die einfachste] WEB-Anwendungsentwicklung mit Apache Tomcat + Java Servlet
Was ich aus Java gelernt habe, funktioniert mit Visual Studio Code