3. Spring Boot + Spring Security 配置的同步异步请求
注: 根据判断前端的请求是同步还是异步,进行返回对应的数据
- ImoccAuthenticationSuccessHandler.java 表示用户登陆成功的授权请求跳转
package com.imooc.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.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.security.core.properties.LoginType;
import com.imooc.security.core.properties.SecurityProperties;
/**
*
* @author cjj
* @date 2018年9月26日
* @email [email protected]
* @blog blog.****.net/qq_29451823
*/
@Component("imoccAuthenticationSuccessHandler")
public class ImoccAuthenticationSuccessHandler /*implements AuthenticationSuccessHandler*/extends SavedRequestAwareAuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
/**
* Authentication 里面保存用户请求的信息和MyUserDetailsService返回的对象的信息
* 是一个接口根据不同的登陆设备,传递不同的对象
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
logger.info("登陆成功");
// response.setContentType("application/json;charset=UTF-8");
// response.getWriter().write(objectMapper.writeValueAsString(authentication));
if(LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
//如果是是异步请求,则需要返回JSON格式
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
} else {
//如果是同步请求,则需要跳转界面
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
2.ImoccAuthenticationFailUrlHandler. java 表示用户登陆失败的授权请求跳转
package com.imooc.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.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.security.core.properties.LoginType;
import com.imooc.security.core.properties.SecurityProperties;
/**
*
* @author cjj
* @date 2018年9月26日
* @email [email protected]
* @blog blog.****.net/qq_29451823
*/
@Component("imoccAuthenticationFailUrlHandler")
public class ImoccAuthenticationFailUrlHandler extends ExceptionMappingAuthenticationFailureHandler/* implements AuthenticationFailureHandler*/ {
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("登陆成功");
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
// response.setContentType("application/json;charset=UTF-8");
// response.getWriter().write(objectMapper.writeValueAsString(exception));
if(LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
//如果是是异步请求,则需要返回JSON格式
response. setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception));
} else {
//如果是同步请求,则需要跳转界面
super.onAuthenticationFailure(request, response, exception);
}
}
}
- BrowserSecurityConfig.java 加载配置
package com.imooc.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 org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import com.imooc.security.core.properties.SecurityProperties;
/**
*
* @author cjj
* @date 2018年9月26日
* @email [email protected]
* @blog blog.****.net/qq_29451823
*/
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private SecurityProperties securityProperties;
@Autowired
private AuthenticationSuccessHandler imoccAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler imoccAuthenticationFailUrlHandler;
/**
* 处理密码加密解密
* @return
*/
@Bean
public PasswordEncoder passwordEncode() {
//PasswordEncoder的一个实现类
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//表单认证
.loginPage("/authentication/require")//添加自定义登陆界面
.loginProcessingUrl("/authentication/from")//这个URL用UsernamePasswordAuthenticationFilter来处理
.successHandler(imoccAuthenticationSuccessHandler)//添加成功处理
.failureHandler(imoccAuthenticationFailUrlHandler)//添加失败处理
//http.httpBasic()//弹出框认证
.and()
.authorizeRequests()//对请求做一个授权
.antMatchers("/authentication/require"
,securityProperties.getBrowser().getLoginPage()).permitAll()//访问这个页面的时候不需要授权
.anyRequest()//任何请求
.authenticated()//身份认证
.and()
.csrf().disable();//关闭跨站请求伪造
}
}
4.判断是同步还是异步
枚举类LoginType.java
package com.imooc.security.core.properties;
public enum LoginType {
REDIRECT,//同步
JSON //异步
}
- 这儿模拟用户自定义设置是同步还是异步,application.properties
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url= jdbc:mysql://127.0.0.1:3306/imooc-demo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
spring.datasource.username = root
spring.datasource.password = root
#spring.session 集群的配置管理
spring.session.store-type = none
#关闭spring.security的默认验证配置
#security.basic.enabled = false
#server.session.timeout = 60
#开启热部署
spring.devtools.restart.enabled=true
server.port = 8060
#imooc.security.browser.loginPage = /demo-signIn.html
imooc.security.browser.loginType = REDIRECT
- BrowserProperties.java
package com.imooc.security.core.properties;
public class BrowserProperties {
//如果用户没有配置,则默认跳转到loginPage
private String loginPage = "/imooc-signIn.html";
//如果用户没有配置,则默认是异步请求
private LoginType loginType = LoginType.JSON;
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public LoginType getLoginType() {
return loginType;
}
public void setLoginType(LoginType loginType) {
this.loginType = loginType;
}
}