We will extend the project created in SQL Server Connection. If you copy and paste in order, you will have a moving object for the time being. I was particular about the order in which errors do not occur during copying. So, does this code exist at this time? Do you need it? There is also a part called. The error checking process is incomplete. Please be forewarned.
Created with the following specifications.
-Extend the project created in SQL Server Connection. --Create your own user table and authenticate. --Create two administrative users and two general users so that you can see the difference in behavior depending on the role. --Only administrative users can register general users. --Only one admin user can be created. --Do not use CSS or JavaScript.
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
Create a UserInfo table to save user information and a UserRoles table to save roles in the DB created in here.
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];
I copied the project created in SQL Server Connection to "D: \ JAVA \ Project \ securitySample" and created it.
pom.xml Add the Repository required for Spring Security and the Repository used to check the number of characters in the password.
<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>
The entire 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.Run the build even if you don't have 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>
Create an entity to store user information.
D:\JAVA\Project\securitySample\src\main\java\com\example\persistence
└─entity
├─UserInfo.java
└─UserRoles.java
UserRoles.java Stores roles (privileges).
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 Stores user information.
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;
}
}
Create a repository to access the DB.
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;
}
}
Create a "security" folder in "D: \ JAVA \ Project \ sqlSample \ src \ main \ java \ com \ example". Create a config folder directly under it. Create the following files in the config folder.
Create the following files directly under the security folder.
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 Specify the page to be displayed when authentication is successful. It is also possible to divide by roll.
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();
//Redirect destination after authentication
if (authentication.getAuthorities().toString().contains("ADMIN")) {
//The ADMIN role displays the user registration page.
redirectStrategy.sendRedirect(request, response, "/userReg/index");
} else {
//The page to be displayed for other roles.
redirectStrategy.sendRedirect(request, response, "/hello/index");
}
}
}
MyAccessDeniedHandler.java Specify the page to be displayed when an error occurs in the authentication process.
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 Add the items you want to add to the standard credentials. The Japanese item of the user name and the department name are added.
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 Basic authentication is not used in this application, but it is described as an example to be used together with Form authentication. The description gives priority to Basic authentication.
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();
}
/**
*Basic authentication
*/
@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()
;
}
}
/**
*Form authentication
*/
@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()
//Accessable for any role
.antMatchers("/", "/resources/**", "/webjars/**", "/auth/**", "/adminReg/**").permitAll()
//Access settings for roles
// '/userReg/'URLs that start with'ADMIN'Only roles can be accessed
.antMatchers("/userReg/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.loginPage("/auth/login")
.failureUrl("/auth/login-error")
.successHandler(new MyAuthenticationSuccessHandler())
.permitAll()
.and()
//Logout processing settings
.logout()
//URL for logout process
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
//Transition destination URL when logout is successful
.logoutSuccessUrl("/auth/login")
//Cookie name to delete when logging out
.deleteCookies("JSESSIONID")
//Enable session destruction on logout
.invalidateHttpSession(true)
.permitAll()
.and()
//Transition destination setting at the time of 403 error
.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 {
}
Add SecurityConfig.class to getRootConfigClasses of WebAppInitializer.
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {SecurityConfig.class, PersistenceConfig.class, ServiceConfig.class};
}
The entire 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 {
/**
*Specifies Java Config classes for non-Spring MVC, such as business logic.
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {SecurityConfig.class, PersistenceConfig.class, ServiceConfig.class};
}
/**
*Specifies the Java Config class for Spring MVC.
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {MvcConfig.class};
}
/**
*Specifies the URL pattern for the DispatcherServlet.
* "/"By specifying, DispatcherServlet receives all requests.
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
*Specify the Servlet filter.
*If there are multiple filters, they will be executed in the order specified in the array.
*/
@Override
protected Filter[] getServletFilters() {
return new Filter[] {
new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)
};
}
}
This completes the necessary preparations for using Spring Security. Next, we will create a login page and an administrative user creation page.
Recommended Posts