基本原理
打开security的依赖
compile('org.springframework.cloud:spring-cloud-starter-security')
打开之后默认就保护了所有的请求路径;访问任意一个都会跳转到一个默认的用户密码登录认证页面,
用户名固定的:user
密码,项目启动日志打印出来的(每次启动都不一样):Using generated security password: 60c4246b-735f-4f59-9a18-0861e1b7130a
默认的肯定不满足我们的需求,来看看怎么自定义配置
代码项目变更
从现在开始要改变项目模块来写安全代码了
启用该模块security-browser
,安全相关的都在这里写,其他项目依赖安全模块即可;
该模块是基于浏览器的开发
注意:对于项目依赖,core的application.yml是不会生效的,只有在bobrowser中的application.yml才会生效
dependencies {
compile project(':security-core')
}
编写第一个配置类
更改默认配置为form表单方式
package cn.mrcode.imooc.springsecurity.securitybrowser;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author : zhuqiang
* @version : V1.0
* @date : 2018/8/3 0:05
*/
// WebSecurityConfigurerAdapter 适配器类。专门用来做web应用的安全配置
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
// 有三个configure的方法,这里使用http参数的
@Override
protected void configure(HttpSecurity http) throws Exception {
// 最简单的修改默认配置的方法
// 在v5+中,该配置(表单登录)应该是默认配置了
// basic登录(也就是弹框登录的)应该是v5-的版本默认
http
// 定义表单登录 - 身份认证的方式
.formLogin()
// .httpBasic() // 切换为basic方式也很简单。感叹一下太强大
.and()
// 对请求授权配置:注意方法名的含义,能联想到一些
.authorizeRequests()
.anyRequest()
// 对任意请求都必须是已认证才能访问
.authenticated();
}
}
基本原理
核心就是一组过滤器链。项目启动自动配置上的。
最核心的就是 Basic Authentication Filter 用来认证用户的身份;
一个过滤器处理一种认证方式;
对于username password认证过滤器来说,
* 会检查是否是一个登录请求,
* 是否包含username 和 password (也就是该过滤器需要的一些认证信息)
* 如果不满足则放行给下一个
下一个按照自身职责判定是否是自身需要的信息,
basic的特征就是在请求头中有 Authorization:Basic eHh4Onh4
的信息
中间可能还有更多的认证过滤器。 最后一环是 FilterSecurityInterceptor ,
这里会判定该请求是否能进行访问rest服务;判断的依据是:BrowserSecurityConfig中的配置;
如果被拒绝了就会抛出不同的异常(根据具体的原因)。
Exception Translation Filter 会捕获抛出的错误,然后根据不同的认证方式进行信息的返回提示
注意的是:绿色的过滤器可以配置是否生效,其他的都不能控制;
以上就是security最基本的一个原理,其他的衍生的功能都是基于这个架子进行扩展的
源码查看
源码查看思路:
上面描述了最基本的流程,这里把上面列出来的几个类关键部分打上断点,然后访问api进行跟进代码
-
org.springframework.security.web.access.intercept.FilterSecurityInterceptor#invoke
大约120行
InterceptorStatusToken token = super.beforeInvocation(fi);
-
org.springframework.security.web.access.ExceptionTranslationFilter#doFilter
大约130行
-
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication
大约68行
-
org.springframework.security.web.authentication.www.BasicAuthenticationFilter#doFilterInternal
大约150行
-
任意一个api服务中
关键调试代码记录
1. 访问一个服务
2. 发现先走了 org.springframework.security.web.access.ExceptionTranslationFilter#doFilter
为什么会先走这里,因为我们随意访问一个服务,都不满足前面几个认证过滤器的要求
3. 执行后到了org.springframework.security.web.access.intercept.FilterSecurityInterceptor#invoke 中的 InterceptorStatusToken token = super.beforeInvocation(fi); 执行后就报错了
4. 返回到了ExceptionTranslationFilter,并且被捕获到了异常信息 Access is denied (拒绝访问)
5. 处理异常信息之后根据配置返回到了登录页面
6. 登录之后,被拦截到 org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication
7. 认证成功之后,又经过了 ExceptionTranslationFilter
8. 接着又到了 FilterSecurityInterceptor 会验证是否有权限访问,如果有的话,InterceptorStatusToken token 会返回值,
9. 下一步放行,由于之前处理的是一个登录请求,所以会有一个重定向,到我们访问的api中
只要不是认证请求的话,前面的认证过滤器是不会走的,反而这两个类的流程都会走一遍 ExceptionTranslationFilter 、FilterSecurityInterceptor ; 看来这两个类是真的固定死的流程架子
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。