继续接着上篇文章 《Spring Security(四):自定义用户认证逻辑》,本篇文章主要介绍如何进行个性化用户认证。
场景:考虑到前后端分离的场景,后端提供接口供前端调用,并返回JSON格式的数据给前端。或请求html请求返回页面,来处理不同类型的请求(html请求或数据请求)。
处理不同类型的请求
1、【zjj-security-browser 工程】修改安全框架的配置类BrowserSecurityConfig
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.core.properties.SecurityProperties;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() // 定义是否使用表单登录
// .loginPage("/zjj-login.html") // 指定html登录页面
.loginPage("/authentication/require") //指定登录请求的controller
.loginProcessingUrl("/authentication/form") // 自定义登录接口
.and()
.authorizeRequests() // 对所有请求进行授权
// .antMatchers("/zjj-login.html").permitAll() // 指定页面不需要进行认证
.antMatchers("/authentication/require", securityProperties.getBrowser().getLoginPage()).permitAll()
.anyRequest() // 任何请求
.authenticated() // 都需要身份认证
.and()
.csrf().disable(); // 关闭csrf防护
}
}
2、【zjj-security-core 工程】创建系统封装配置类 SecurityProperties
@ConfigurationProperties(prefix = "zjj.security")
public class SecurityProperties {
private BrowserProperties browser = new BrowserProperties();
public BrowserProperties getBrowser() {
return browser;
}
public void setBrowser(BrowserProperties browser) {
this.browser = browser;
}
}
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";
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
}
3、【zjj-security-core 工程】@EnableConfigurationProperties开启配置属性生效
package com.zjj.security.core;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import com.zjj.security.core.properties.SecurityProperties;
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}
4、【zjj-security-demo 工程】application.yml,配置html请求指定认证跳转页面
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://10.2.100.126:3306/sklweb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: gx*d1/1),7=V
# session会话 先关闭
session:
store-type: none
# 身份开启 spring security 当值为true 则需要进行认证登录操作
security:
basic:
enabled: true
# 配置html请求指定认证跳转页面
zjj:
security:
browser:
loginPage: /demo-sign.html
5、【zjj-security-demo 工程】在\src\main\resources下新建文件夹resources,并创建demo-sign.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
Demo的html登录页面
</body>
</html>
6、【zjj-security-browser工程】创建指定自定义登录请求的controller
package com.zjj.security.browser;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.zjj.security.browser.vo.SimpleResponse;
import com.zjj.security.core.properties.SecurityProperties;
@RestController
public class BrowserSecurityController {
private Logger logger = LoggerFactory.getLogger(getClass());
private RequestCache requestCache = new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Autowired
private SecurityProperties securityProperties;
/**
* 当需要身份认证时,跳转到这里
*
* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping("/authentication/require")
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response)
throws IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest != null) {
String targetUrl = savedRequest.getRedirectUrl();
logger.info("引发跳转的请求是:" + targetUrl);
if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
redirectStrategy.sendRedirect(request, response, securityProperties.getBrowser().getLoginPage());
}
}
return new SimpleResponse("访问的服务需要身份认证,请引导用户到登录页");
}
}
7、【zjj-security-browser工程】创建封装响应的JSON类
package com.zjj.security.browser.vo;
public class SimpleResponse {
public SimpleResponse(Object content){
this.content = content;
}
private Object content;
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
8、【zjj-security-browser工程】启动ZjjSecurityDemoApplication 类main方法
a、当访问 http://localhost:8080/hi 时,会首先跳转到 http://localhost:8080/authentication/require 请求页面,并显示
{"content": "访问的服务需要身份认证,请引导用户到登录页"}
b、当访问 http://localhost:8080/xxx.html 任意的html时,会首先跳转到 http://localhost:8080/demo-sign.html 请求页面,并显示
Demo的html登录页面
c、扩展:当屏蔽【zjj-security-demo 工程】application.yml的zjj.security.browser.loginPage配置,重起main方法,并访问 http://localhost:8080/xxx.html 任意的html时,则会首先跳转到默认 http://localhost:8080/zjj-login.html 请求页面
9、处理不同类型的请求操作完成
更多内容请关注我的个人博客:http://www.zjjfx68.com/