[JAVA] Développement d'applications Web Spring 5 MVC avec Visual Studio Code Utilisation de Spring Security 1/3 [Préparation]

introduction

Nous allons étendre le projet créé dans Connexion SQL Server. Si vous copiez et collez dans l'ordre, vous aurez un objet en mouvement pour le moment. J'étais particulier sur l'ordre dans lequel aucune erreur ne s'est produite pendant la copie. Alors, ce code existe-t-il en ce moment? En as-tu besoin? Il y a aussi une partie appelée. Le processus de vérification des erreurs est incomplet. Soyez prévenu.

Créé avec les spécifications suivantes.

-Extend le projet créé dans Connexion SQL Server. --Créez votre propre table d'utilisateurs et effectuez l'authentification.

environnement

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

Procédure de création

  1. Créez une table pour stocker les informations utilisateur
  2. Création de l'entité et du référentiel requis pour l'accès à la base de données
  3. Paramètres d'utilisation de Spring Security
  4. Créez une page d'enregistrement d'utilisateur administratif
  5. Création d'une page d'inscription utilisateur générale

Créer une table pour stocker les informations utilisateur

Créez une table UserInfo pour enregistrer les informations utilisateur et une table UserRoles pour enregistrer les rôles dans la base de données créée dans ici.

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];

Création de projet

J'ai copié le projet créé dans Connexion SQL Server dans «D: \ JAVA \ Project \ securitySample» et l'ai créé.

pom.xml Ajoutez le référentiel requis pour Spring Security et le référentiel utilisé pour vérifier le nombre de caractères dans le mot de passe.

<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>

L'ensemble du fichier 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.Exécutez la compilation même sans xml-->
        <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>

Création d'entité

Créez une entité pour stocker les informations utilisateur.

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

UserRoles.java Stocke les rôles (privilèges).

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 Stocke les informations utilisateur.

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;
	}
}

Créer un référentiel

Créez un référentiel pour accéder à la base de données.

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;
    }
}

Création d'un service de sécurité

Créez un dossier "security" dans "D: \ JAVA \ Project \ sqlSample \ src \ main \ java \ com \ example". Créez un dossier de configuration directement en dessous. Créez les fichiers suivants dans le dossier config.

Créez les fichiers suivants directement sous le dossier de sécurité.

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 Spécifiez la page à afficher lorsque l'authentification est réussie. Il est également possible de diviser par rouleau.

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();

        //Rediriger la destination après l'authentification
        if (authentication.getAuthorities().toString().contains("ADMIN")) {
            //Le rôle ADMIN affiche la page d'inscription de l'utilisateur.
        	redirectStrategy.sendRedirect(request, response, "/userReg/index");
        } else {
            //La page à afficher pour les autres rôles.
        	redirectStrategy.sendRedirect(request, response, "/hello/index");
        }
    }
}

MyAccessDeniedHandler.java Spécifiez la page à afficher lorsqu'une erreur se produit dans le processus d'authentification.

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 Ajoutez les éléments que vous souhaitez ajouter aux informations d'identification standard. L'élément japonais du nom d'utilisateur et le nom du service sont ajoutés.

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 L'authentification de base n'est pas utilisée dans cette application, mais elle est décrite comme un exemple à utiliser avec l'authentification par formulaire. La description donne la priorité à l'authentification de base.

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();
    }
	/**
	 *Authentification de base
	 */
	@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()
            ;
		}
	}

	/**
	 *Authentification par formulaire
	 */
	@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()

			  	//Accessible pour n'importe quel rôle
		  		.antMatchers("/", "/resources/**", "/webjars/**", "/auth/**", "/adminReg/**").permitAll()

		  		//Accéder aux paramètres des rôles
		  		// '/userReg/'URL commençant par'ADMIN'Seuls les rôles sont accessibles
			    .antMatchers("/userReg/**").hasRole("ADMIN")

			  	.anyRequest().authenticated()
			  	.and()
			  		.formLogin()
			  		.loginProcessingUrl("/login")
			  		.loginPage("/auth/login")
			  		.failureUrl("/auth/login-error")
			  		.successHandler(new MyAuthenticationSuccessHandler())
			  		.permitAll()
		        .and()
		        //Paramètres de traitement de déconnexion
		        	.logout()
		            //URL du processus de déconnexion
		            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
		            //URL de destination de la transition lorsque la déconnexion est réussie
		            .logoutSuccessUrl("/auth/login")
		            //Nom du cookie à supprimer lors de la déconnexion
		            .deleteCookies("JSESSIONID")
		            //Activer la destruction de session lors de la déconnexion
		            .invalidateHttpSession(true)
		            .permitAll()
		        .and()
		        //403 Réglage de la destination de transition au moment de l'erreur
		        	.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 {

}

Ajout de WebAppInitializer.java

Ajoutez SecurityConfig.class à getRootConfigClasses de WebAppInitializer.

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

L'ensemble de 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 {
    /**
     *Spécifie les classes Java Config pour MVC non Spring, telles que la logique métier.
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {SecurityConfig.class, PersistenceConfig.class, ServiceConfig.class};
    }

    /**
     *Spécifie la classe Java Config pour Spring MVC.
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {MvcConfig.class};
    }

    /**
     *Spécifiez le modèle d'URL pour DispatcherServlet.
     * "/"En spécifiant, DispatcherServlet reçoit toutes les demandes.
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     *Spécifiez le filtre de servlet.
     *S'il y a plusieurs filtres, ils seront exécutés dans l'ordre spécifié dans le tableau.
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] {
                new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)
            };
    }
}

Résumé

Ceci termine les préparatifs nécessaires à l'utilisation de Spring Security. Ensuite, nous allons créer une page de connexion et une page de création d'utilisateur administratif.

Recommended Posts

Développement d'applications Web Spring 5 MVC avec Visual Studio Code Utilisation de Spring Security 1/3 [Préparation]
Développement d'applications Web Spring 5 MVC avec Visual Studio Code Utilisation de Spring Security 2/3 [Création de page 1/2]
Développement d'applications Web Spring 5 MVC avec Visual Studio Code Utilisation de Spring Security 3/3 [Création de page 2/2]
Développement d'applications Web Spring5 MVC avec connexion Visual Studio Code SQL Server
Développement d'applications Web Spring5 MVC avec création de modèles Visual Studio Code Maven
Développement d'applications Web Spring5 MVC avec Visual Studio Code Hello World Creation
Développement d'applications Web Spring Boot2 avec connexion Visual Studio Code SQL Server
Développement d'applications Web Spring Boot2 avec création de Visual Studio Code Hello World
Développement d'applications Web Spring5 MVC avec construction de l'environnement de code Visual Studio (installation de JDK11 / Maven / Tomcat / Visual Studio Code)
Créer un environnement de développement Web APP avec Java + Spring avec Visual Studio Code
Démarrez le développement d'applications Web avec Spring Boot
Mémo d'utilisation de Spring Security: coopération avec Spring MVC et Boot
Créer un environnement de développement de programme Java avec Visual Studio Code
Construction d'environnement de développement d'applications Web Java avec VS Code (struts2)
Utiliser PlantUML avec Visual Studio Code
Exécutez l'application WEB avec Spring Boot + Thymeleaf
Un enregistrement de la configuration d'un environnement de développement Java avec Visual Studio Code
Découvrez .NET 5 avec Docker et Visual Studio Code
Prise en main des programmes Java à l'aide de Visual Studio Code
Pourquoi pouvez-vous développer Java avec Visual Studio Code?
À peu près le flux de développement d'applications Web avec Rails.
Préparation au développement d'applications Android 7/15
Mémo de développement d'applications Web avec MVN, Tomcat, JSP / Servlet avec VScode
La première application WEB avec Spring Boot-Making a Pomodoro timer-
Pour recevoir une demande vide avec Spring Web MVC @RequestBody
Configuration Java avec Spring MVC
Mémo d'utilisation de Spring Security CSRF
Mémo d'utilisation de Spring Security Run-As
[Spring Boot] Création d'applications Web
Spring Security Usage Memo Method Security
Mémo d'utilisation de Spring Security Remember-Me
Résumé de l'article sur le développement d'applications Web
Fonction de connexion avec Spring Security
Java avec Visual Studio Code
Application Web construite avec docker (1)
Mémo d'utilisation de Spring Security CORS
Test de mémo d'utilisation de Spring Security
Comparaison du développement d'applications WEB avec Rails et Java Servlet + JSP
Comment utiliser PlantUML avec Visual Studio Code (créé le 30 octobre 2020)
Créons une application Web de gestion de livres avec Spring Boot part1
Créons une application Web de gestion de livres avec Spring Boot part3
Créons une application Web de gestion de livres avec Spring Boot part2
[Probablement le plus simple] Développement d'applications WEB avec Apache Tomcat + Java Servlet
Ce que j'ai appris en travaillant Java avec Visual Studio Code