Spring Security
2021-12-17 19:17:00 66 举报
AI智能生成
登录查看完整内容
Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架。它是保护基于Spring的应用程序的实际标准。Spring Security是一个能够为基于JavaEE的企业级应用程序提供身份认证和授权服务的框架。与所有Spring项目一样,Spring Security的真正强大之处在于它的自动化配置和扩展性。借助于自动配置,我们可以快速构建安全应用程序,而无需手动配置每个详细设置。同时,它还提供了许多可插拔的安全功能,例如OAuth2、JWT等,可以灵活地满足各种安全需求。总之,Spring Security是一个值得学习和使用的强大的安全框架。
作者其他创作
大纲/内容
Oauth2认证
Spring Security Oauth2
Spring Security Oauth2 整合单点登录(SSO)
SpringSecurity简介
导入依赖
自己写的登陆页面login.html
默认的 username 为 user,password 打印在控制台中(每次重新启动都会刷新)
启动项目
快速入门
需要自定义逻辑时,只需要实现 UserDetailsService 接口即可
重写loadUserByUsername方法,返回值是一个UserDetailsUserDetails是一个接口,我们只需返回它的一个实现类User注意 User 的全限定路径是:`org.springframework.security.core.userdetails.User`此处经常和系统中自己开发的 User 类弄混我们也可以自己编写一个User类实现UserDetails,进行我们需要的操作
构造方法
若要修改参数名需要在配置类配置
方法参数
异常
通过AuthorityUtils.commaSeparatedStringToAuthorityList(“”)来创建authorities集合对象的。参数是一个字符串,多个权限使用逗号分隔。
设置权限
UserDetails接口
UserDetailsService详解
Spring Security 要求容器中必须有`PasswordEncoder`实例所以不能直接new对象,所以当自定义登录逻辑时要求必须给容器注入`PaswordEncoder`的bean对象在SecurityConfig中@Bean添加到容器UserDetailsServiceImpl用的上,要注入
接口方法
内置解析器(即实现类)
PasswordEncoder 密码解析器详解
在 Spring Security 中实现 UserDetailService 就表示为用户详情服务
loginPage()
loginProcessingUrl()
usernamePasrameter(String)
passwordParameter(String)
默认情况只允许post请求登陆
=============
successForwardUrl()
failureForwardUrl()
配置类表单登陆相关方法http.formLogin()
4步
根据源码照葫芦画瓢
1、实现AuthenticationSuccessHandler接口
2、定义变量url
3、编写构造方法(传url)
4、重写onAuthenticationSuccess方法,实现重定向
5、SecurityConfig中配置http.formLogin() //最好@Autowired注入 .successHandler(new MyAuthenticationSuccessHandler(\"http://www.baidu.com\"))
自定义登录成功处理器
MyAuthenticationSuccessHandler
同理
自定义登录失败处理器
自定义登陆逻辑
自定义登录页面
实现自定义登录
在所有匹配规则中取所有规则的交集。配置顺序影响了之后授权效果,越是具体的应该放在前面,越是笼统的应该放到后面。
匹配所有的请求
所有请求都必须认证才能访问,必须登陆 必须放在最后.anyRequest().authenticated();
自定义url访问.anyRequest().access(\
anyRequest()
单参数:参数是不定向参数,每个参数是一个 ant 表达式,用于匹配 URL规则
antMatcher()
单参数:使用正则表达式进行匹配。和 antMatchers()主要的区别就是参数
regexMatchers()
适用于配置了 servletPath(指的是图片第一种) 的情况
server.servlet.context-path:上下文路径spring.mvc.servlet.path:DispatcherServlet 的拦截路径意思是哪些访问路径需要被spring的dispatcher servlet处理
注意!!!context-path和path的区别
.mvcMatchers(\"/demo\").servletPath(\"/novo\").permitAll()
mvcMatchers()(用的不多)
访问控制url匹配
两个参数时使用方式
接在URL匹配规则之后
permitAll()
包括rememberMe通过免登陆进来和fullyAuthenticated通过用户名和密码进来两种情况
authenticated()
和permitAll区别不大,用到比较少
anonymous()
denyAll()
rememberMe()
fullyAuthenticated()
内置访问控制方法
用户的权限hasAuthority(String)
hasAnyAuthority(String ...)
用户的角色hasRole(String)
hasAnyRole(String ...)
hasIpAddress(String)用的不多
角色、权限判断
设置权限:在自定义登录逻辑 UserDetailsService 实现类中创建 User 对象时给 User 赋予的授权
SpringSecurity官方文档
权限表达式的使用 官方文档
都是调用access(表达式)
举例:.antMatchers(\"/login.html\").access(\"permitAll\") 等价于.antMatchers(\"/login.html\").permitAll()
.antMatchers(\"/main1.html\").access(\
例:判断已登录用户是否具有访问当前 URL 权限登陆成功后跳转到main.html我们去设置main.html这个url是否有权限被访问
MyService.java
MyServiceImpl.java
1、新建接口及实现类
在 access 中通过@bean的id名.方法(参数)的形式进行调用即唯一标识id名首字母要小写
2、修改配置类SecurityConfig
自定义逻辑
基于表达式的访问控制
比较常用:@PreAuthorize
注解默认值为false,不可用要在引导类上加@EnableGlobalMethodSecurity开启具体的注解
如果设置的条件允许,程序正常执行。如果不允许会报 500其实是先判断有没有登陆,如果登陆成功后还是没有权限才会报500,在此前我们没有权限是403这些注解可以写到 Service 接口或方法上,也可以写到 Controller或 Controller 的方法上。通常情况下都是写在控制器方法上的,控制接口URL是否允许被访问。因为controller有对应的url,而如果写在service上,同一个service可以被不同的controller调用,比较难以控制
注解方式和配置类方式只能二选一
专门用于判断是否具有角色的。能写在方法或类上
注意区分什么时候参数要加ROLE_:大小写依然严格区分基于注解@Secured的value属性要以 ROLE_开头基于注解@PreAuthorize的access表示式:可以加ROLE_也可以不加基于配置类access表示式的一定不能加ROLE_
@Secured
表示访问方法或类在执行之前先判断权限,大多情况下都是使用这个注解,注解的参数和access()方法参数取值相同,都是权限表达式。
@PreAuthorize
表示方法或类执行结束后判断权限,此注解很少被使用到
基于注解的访问控制
底层实现
访问控制(授权)
实现 AccessDeniedHandler
字符输出流:PrintWriter getWriter()这是response获取的字符流 在一次响应结束后会自动close和flush
设置头信息application/json:返回jsoncharset避免中文乱码
//添加异常处理 http.exceptionHandling() //推荐注入 .accessDeniedHandler(new MyAccessDeniedHandler());
自定义403处理方案
MySQL时区问题:UTC是是全球标准时间 ,但是我们使用的时间是北京时区也就是东八区,领先UTC八个小时为了remember配置自动建表里的时间字段与系统时间匹配需要设置 serverTimezone=Asia/Shanghai
配置数据源
可以新建一个RememberMe的配置类来注入数据源和设置jdbcTokenRepository相关配置也可以直接写在SecurityConfig里
last_userd最新一次重新输入用户名密码登陆的时间,重新登陆会新增一条数据token过期后,再尝试免登陆会报错,再清空该条数据
persistent_logins表里的字段
编写配置
添加RememberMeConfig和UserDetailsService实现类对象,并自动注入。在 configure 中添加http.rememberMe()
修改SecurityConfig
注意标签name默认值是remember-me如果修改了,需要http.rememberMe().rememberMeParameter(\"标签名\")
登陆页面添加复选框
不修改配置情况下默认是2周但是可以通过设置状态有效时间.tokenValiditySeconds(60)计时是从关闭浏览器开始持续的时间,如果设置了60s,关闭浏览器30s后重新打开再关闭浏览器会重新计时
有效时间
RememberMe
实现非常简单点击退出后默认跳转路径是/login.html?logout
不使用默认值,修改配置
退出默认销毁 HttpSession 对象和清除认证状态
addLogoutHandler(LogoutHandler)
clearAuthentication(boolean)
invalidateHttpSession(boolean)
logoutSuccessHandler(LogoutSuccessHandler)
其他方法(一般不用)
实现
退出登陆
刚开始学习Spring Security时,在配置类中一直存在这样一行代码:http.csrf().disable();如果没有这行代码导致用户无法被认证。这行代码的含义是:关闭 csrf 防护
为什么需要CSRF
无状态
Token相对cookie的优势
前端表单通过隐藏域拿到token
CSRF
CORS
CSRF/CORS
SpringSecurity
JWT
Spring Security Oauth2 整合JWT
0 条评论
回复 删除
下一页