版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29451823/article/details/82853303
逻辑原理:
用户访问系统项目随便一个URL,会判断用户提供信息中是否带有账号密码,如果有则,直接进入自定义的表单登陆,如果没有,则会跳转到FilterSecurity Interceptor拦截器,进行判断,则会抛出异常,由Exception Translation Filter进行捕获,根据相应的情况(例如没有登陆用户,或者登陆了权限不够等)重定向到自定义的登陆界面。
- 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 com.imooc.security.core.properties.SecurityProperties;
/**
*
* @author cjj
* @date 2018年9月26日
* @email [email protected]
* @blog blog.csdn.net/qq_29451823
*/
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private SecurityProperties securityProperties;
/**
* 处理密码加密解密
* @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来处理
//http.httpBasic()//弹出框认证
.and()
.authorizeRequests()//对请求做一个授权
.antMatchers("/authentication/require"
,securityProperties.getBrowser().getLoginPage()).permitAll()//访问这个页面的时候不需要授权
.anyRequest()//任何请求
.authenticated()//身份认证
.and()
.csrf().disable();//关闭跨站请求伪造
}
}
- BrowserSecurityController.java 进入跳转控制中心进行判断,如果URL是访问一个.hmtl页面,则进入自定义的登陆界面,如果是其他类型的,则提示用户到登陆界面上去!
package com.imooc.security.browser;
import java.io.IOException;
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.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.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.imooc.security.core.properties.SecurityProperties;
/**
*
* @author cjj
* @date 2018年9月21日
* @email [email protected]
* @blog blog.csdn.net/qq_29451823
*/
@RestController
public class BrowserSecurityController {
//缓存最开始引发跳转的请求
private RequestCache requestCache = new HttpSessionRequestCache();
private Logger logger = LoggerFactory.getLogger(getClass());
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);
//判断访问的url是否为一个.HTML后缀格式的请求
if(StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
//重定向
redirectStrategy.sendRedirect(request, response, securityProperties.getBrowser().getLoginPage());
}
}
return new SimpleResponse("返回的服务需要身份认证,请引到用户到登陆页面");
}
}
- SimpleResponse 封装返回的类型
package com.imooc.security.browser;
public class SimpleResponse {
private Object content;
public SimpleResponse(Object content) {
this.content = content;
}
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
- 跳转路径页面的配置
将所有参数放在BrowserProperties 里面
package com.imooc.security.core.properties;
public class BrowserProperties {
//如果用户没有配置,则默认跳转到loginPage
private String loginPage = "/imooc-signIn.html";
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
}
SecurityProperties.java 主要是加载Properties 配置文件
package com.imooc.security.core.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 读取所有以imooc.security开头的properties配置项
* @author cjj
* @date 2018年9月21日
* @email [email protected]
* @blog blog.csdn.net/qq_29451823
*/
@ConfigurationProperties(prefix = "imooc.security")
public class SecurityProperties {
private BrowserProperties browser = new BrowserProperties();
public BrowserProperties getBrowser() {
return browser;
}
public void setBrowser(BrowserProperties browser) {
this.browser = browser;
}
}
SecurityCoreConfig.java 加载SecurityProperties.class
package com.imooc.security.core;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import com.imooc.security.core.properties.SecurityProperties;
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}
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
#用户配置的自定义登陆html页面路径
imooc.security.browser.loginPage = /demo-signIn.html