继续接着上篇文章 《Spring Security(四):自定义用户认证逻辑》,本篇文章主要介绍如何进行个性化用户认证。

场景:考虑到前后端分离的场景,后端提供接口供前端调用,并返回JSON格式的数据给前端。或请求html请求返回页面,来处理不同类型的请求(html请求或数据请求)。

处理不同类型的请求

 


Spring Security(五):个性化用户认证流程

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、处理不同类型的请求操作完成

 


源码下载
Spring Security 码云目录一览

更多内容请关注我的个人博客:http://www.zjjfx68.com/ 

相关文章: