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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>login</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>login</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--要访问templates 文件下的html 需要这个依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
---------------------------------------------------------------------------------------------------------------------------------------------------------------
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<script src="js/jquery-3.4.1.min.js"></script>l
<script>
$(function () {
$("#login").click(function () {
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
url: "logon2",
method:"post",
data: JSON.stringify({username: username,password:password}),
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (response) {
alert(JSON.stringify(response))
},
error: function (response) {
alert("error")
}
})
})
$("#register").click(function () {
var username = $("#username").val;
var password = $("#password").val;
$.ajax({
url: "register",
method:"post",
data: JSON.stringify({username: username,password:password}),
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (response) {
alert(JSON.stringify(response))
},
error: function (response) {
alert("error")
}
})
})
})
</script>
</head>
<body>
username: <input type="text" name="username" id="username"/><br>
password: <input type="text" name="username" id="password"/><br>
<button style="width: 50px;height: 25px" id="login"> submit </button>
<button style="width: 50px;height: 25px" id="register"> submit </button>
</body>
</html>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SecurityConfig class
package com.example.login.config;
import com.example.login.filter.CustomUsernamePasswordFilter;
import com.example.login.handler.CustomEntryPoint;
import com.example.login.handler.LoginFailedHandler;
import com.example.login.handler.LoginSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.*;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import javax.xml.ws.http.HTTPBinding;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin")
.password("{noop}123456")
.roles("USER")
.and()
.withUser("user")
.password("{noop}123456")
.roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/logon","/js/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
//.formLogin()
// .loginPage()
.exceptionHandling()
.authenticationEntryPoint(new CustomEntryPoint())
.and()
.csrf()
.disable();
http.addFilterAt(customUsernamePasswordFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAt(concurrentSessionFilter(),ConcurrentSessionFilter.class);
}
@Bean
public ConcurrentSessionFilter concurrentSessionFilter(){
return new ConcurrentSessionFilter(sessionRegistry());
}
@Bean
public SessionRegistry sessionRegistry(){
return new SessionRegistryImpl();
}
@Bean
public CustomUsernamePasswordFilter customUsernamePasswordFilter() throws Exception{
CustomUsernamePasswordFilter filter = new CustomUsernamePasswordFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(new LoginSuccessHandler());
filter.setAuthenticationFailureHandler(new LoginFailedHandler());
filter.setSessionAuthenticationStrategy(compositeSessionAuthenticationStrategy());
return filter;
}
@Bean
public CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy(){
ConcurrentSessionControlAuthenticationStrategy strategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
strategy.setMaximumSessions(1);
List<SessionAuthenticationStrategy> list = new ArrayList<>();
list.add(strategy);
list.add(new SessionFixationProtectionStrategy());
list.add(new RegisterSessionAuthenticationStrategy(sessionRegistry()));
return new CompositeSessionAuthenticationStrategy(list);
}
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
--------------------------------------------------------------------------------------------------------------------------
CustomUsernamePasswordFilter class
package com.example.login.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
public class CustomUsernamePasswordFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
public CustomUsernamePasswordFilter(){
super(new AntPathRequestMatcher("/logon2","POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
if(!httpServletRequest.getMethod().equals("POST")){
throw new AuthenticationServiceException("Authentication method not supported: " + httpServletRequest.getMethod());
}
ObjectMapper objectMapper = new ObjectMapper();
Map<String,Object> map = objectMapper.readValue(httpServletRequest.getInputStream(), Map.class);
String username = this.obtainUsername(map);
String password = this.obtainPassword(map);
if(username == null){
username = "";
}
if(password == null){
password = "";
}
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password);
return this.getAuthenticationManager().authenticate(token);
}
protected String obtainPassword(Map<String,Object> map) {
return Objects.toString(map.get(SPRING_SECURITY_FORM_PASSWORD_KEY));
}
protected String obtainUsername(Map<String,Object> map){
return Objects.toString(map.get(SPRING_SECURITY_FORM_USERNAME_KEY));
}
@Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
--------------------------------------------------------------------------------------------------------------------------------------
CustomEntryPoint class
package com.example.login.handler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CustomEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.getWriter().write("{\"message\":\"error\"}");
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LoginFailedHandler class
package com.example.login.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class LoginFailedHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
Map<String ,String > map = new HashMap(){{
put("status", "00001");
put("message", "login failed");
}};
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(map);
httpServletResponse.getWriter().write(result);
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------
package com.example.login.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
Map<String ,String > map = new HashMap(){{
put("status", "0000");
put("message", "login success");
}};
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(map);
httpServletResponse.getWriter().write(result);
}
}
-------------------------------------------------
application.properties 采用默认 配置需要进行特殊配置