基本思路:实现AuthenticationSuccessHandler或AuthenticationFailureHandler接口,并进行相应的配置就可以了。当然框架有默认的实现类,也可以继承实现类再来自定义自己的业务。
操作流程
1、【zjj-security-demo 工程】修改application.yml
屏蔽属性loginPage,为后面一会测试使用,新增属性loginType 用于登录成功返回的是跳转页面还是返回JSON使用
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: 用户名
password: 密码
# session会话 先关闭
session:
store-type: none
# 身份开启 spring security 当值为true 则需要进行认证登录操作
security:
basic:
enabled: true
# 配置html请求指定认证跳转页面
zjj:
security:
browser:
# 屏蔽属性loginPage,新增属性loginType 用于登录成功返回的是跳转页面还是返回JSON使用
# loginPage: /demo-sign.html
loginType: REDIRECT
2、【zjj-security-core工程】BrowserProperties配置类,新增对应属性
package com.zjj.security.core.properties;
public class BrowserProperties {
// loginPage = "/zjj-login.html":当zjj-security-demo 不配置 zjj.security.browser.loginPage 时默认跳转的页面
private String loginPage = "/zjj-login.html";
// 设置默认返回的类型
private LoginResponseType loginType = LoginResponseType.JSON;
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public LoginResponseType getLoginType() {
return loginType;
}
public void setLoginType(LoginResponseType loginType) {
this.loginType = loginType;
}
}
3、【zjj-security-core工程】新增枚举类,用于设置登录返回的类型
package com.zjj.security.core.properties;
public enum LoginResponseType {
/**
* 跳转
*/
REDIRECT,
/**
* 返回json
*/
JSON
}
登录成功处理
1、【zjj-security-broswer工程】新增类,实现AuthenticationSuccessHandler接口或继承相关实现类
根据需要返回的不同类型,做出处理
package com.zjj.security.browser.authentication;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zjj.security.core.properties.LoginResponseType;
import com.zjj.security.core.properties.SecurityProperties;
@Component("zjjAuthenticationSuccessHandler")
public class ZjjAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
logger.info("登录成功");
if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
} else {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
2、【zjj-security-broswer工程】config 类定义用户登录成功的处理
package com.zjj.security.browser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.zjj.security.browser.authentication.ZjjAuthenticationFailureHandler;
import com.zjj.security.browser.authentication.ZjjAuthenticationSuccessHandler;
import com.zjj.security.core.properties.SecurityProperties;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Autowired
private ZjjAuthenticationSuccessHandler zjjAuthenticationSuccessHandler;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() // 定义是否使用表单登录
.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form") // 自定义登录接口
.successHandler(zjjAuthenticationSuccessHandler) // 定义用户登录成功的处理
.and()
.authorizeRequests() // 对所有请求进行授权
.antMatchers("/authentication/require", securityProperties.getBrowser().getLoginPage()).permitAll()
.anyRequest() // 任何请求
.authenticated() // 都需要身份认证
.and()
.csrf().disable(); // 关闭csrf防护
}
}
3、【zjj-security-demo 工程】在\src\main\resources下新建文件夹resources,并创建index.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
index
</body>
</html>
4、【 zjj-security-demo工程 】启动ZjjSecurityDemoApplication 类main方法
a、设置zjj-security-demo工程application.yml中的zjj.security.browser.loginType=REDIRECT 并访问 http://localhost:8080/index.html,登录成功后返回到 http://localhost:8080/index.html 并打印
index
b、设置zjj-security-demo工程application.yml中的zjj.security.browser.loginType=JSON 并访问 http://localhost:8080/index.html,登录成功后页面打印
{
"authorities": [{
"authority": "admin"
}],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": "CFC97202A3E9F18084DD5C1E977CF0DA"
},
"authenticated": true,
"principal": {
"password": null,
"username": "zjj",
"authorities": [{
"authority": "admin"
}],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
},
"credentials": null,
"name": "zjj"
}
登录失败处理
1、【zjj-security-broswer工程】新增类,实现AuthenticationSuccessHandler接口或继承相关实现类
根据需要返回的不同类型,做出处理
package com.zjj.security.browser.authentication;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zjj.security.core.properties.LoginResponseType;
import com.zjj.security.core.properties.SecurityProperties;
@Component("zjjAuthenticationFailureHandler")
public class ZjjAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
logger.info("登录失败");
if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
// 设置返回的状态码
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception.getMessage()));
} else {
super.onAuthenticationFailure(request, response, exception);
}
}
}
2、【zjj-security-broswer工程】config 类定义用户登录失败的处理
package com.zjj.security.browser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.zjj.security.browser.authentication.ZjjAuthenticationFailureHandler;
import com.zjj.security.browser.authentication.ZjjAuthenticationSuccessHandler;
import com.zjj.security.core.properties.SecurityProperties;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Autowired
private ZjjAuthenticationSuccessHandler zjjAuthenticationSuccessHandler;
@Autowired
private ZjjAuthenticationFailureHandler zjjAuthenticationFailureHandler;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() // 定义是否使用表单登录
.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form") // 自定义登录接口
.successHandler(zjjAuthenticationSuccessHandler) // 定义用户登录成功的处理
.failureHandler(zjjAuthenticationFailureHandler) // 定义用户登录失败的处理
.and()
.authorizeRequests() // 对所有请求进行授权
.antMatchers("/authentication/require", securityProperties.getBrowser().getLoginPage()).permitAll()
.anyRequest() // 任何请求
.authenticated() // 都需要身份认证
.and()
.csrf().disable(); // 关闭csrf防护
}
}
3、【 zjj-security-demo工程 】启动ZjjSecurityDemoApplication 类main方法
a、设置zjj-security-demo工程application.yml中的zjj.security.browser.loginType=REDIRECT 并访问 http://localhost:8080/index.html,登录失败后返回到 http://localhost:8080/authentication/form 并打印
There was an unexpected error (type=Unauthorized, status=401).
Authentication Failed: 坏的凭证
b、设置zjj-security-demo工程application.yml中的zjj.security.browser.loginType=JSON 并访问 http://localhost:8080/index.html,登录失败后返回到 http://localhost:8080/authentication/form 并打印
"坏的凭证"
更多内容请关注我的个人博客:http://www.zjjfx68.com/