springsecurity(学习自用)
springsecurity
学习资源:
https://blog.csdn.net/qq_45525848/article/details/131142179
- springboot
- spring security
- 认证: 判断用户是否是系统合法用户过程
- 授权: 判断系统内用户可以访问或具有访问那些资源权限过程
创建一个springboot项目
- 如果只创建一个controller,不导入springsecurity的依赖,通过localhost:8080/页面就可以访问了。
- 如果导入springsecurity依赖,那么访问页面时会自动跳转到登录页面,默认登录名为user,密码为控制台自动生成打印的密码。
为什么只导入依赖就可以有登陆页面,并拦截所有的页面转到登陆页面?
默认情况下Spring Boot 在对 Spring Security 进入自动化配置时,会创建一个名为 SpringSecurityFilerChain 的过滤器,并注入到 Spring 容器中,这个过滤器将负责所有的安全管理,包括用户认证、授权、重定向到登录页面等。
SpringBootWebSecurityConfiguration这个类是 spring boot 自动配置类,通过这个源码得知,默认情况下对所有请求进行权限控制:
@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http.authorizeRequests().anyRequest()
.authenticated().and().formLogin().and().httpBasic();
return http.build();
}
}
这就是为什么在引入 Spring Security 中没有任何配置情况下,请求会被拦截的原因!
- 条件一 classpath中存在 SecurityFilterChain.class, HttpSecurity.class
- 条件二 没有自定义 WebSecurityConfigurerAdapter.class, SecurityFilterChain.class
默认情况下,条件都是满足的。 - WebSecurityConfigurerAdapter 这个类极其重要,Spring Security 核心配置都在这个类中。
- 如果要对 Spring Security 进行自定义配置,就要自定义这个类实例,通过覆盖类中方法达到修改默认配置的目的。
访问页面时自动跳转登录页面的实现流程:
- 比如请求/hello接口,在引入spring security依赖之后就会经过一些过滤器intercepter
- 当请求到达FilterSecurityInterceptor时,发现请求没有被认证就会拦截下来,并抛出AccessDeniedException异常
- 抛出这个异常就会被ExceptionTranslationFilter捕获,在这个拦截器中会调用LoginUrlAuthenticationEntryPoint#commence方法,给客户端返回302,并要求客户端重定向到登录页面
- 客户端就会发送登录请求/login
- 请求/login会被DefaultLoginPageGeneratingFilter拦截下来,并在拦截器中返回生成登录页面
就是通过这种方式,Spring Security 默认过滤器中生成了登录页面,并返回。
生成默认用户
通过源码分析能得知 UserDetailService 是顶层父接口,接口中 loadUserByUserName 方法是用来在认证时进行用户名认证方法,默认实现使用是内存实现,如果想要修改数据库实现我们只需要自定义 UserDetailService 实现,最终返回 UserDetails 实例即可。
满足以下两个条件:
- 从自动配置源码中得知当 classpath 下存在 AuthenticationManager 类
- 当前项目中,系统没有提供 AuthenticationManager.class、 AuthenticationProvider.class、UserDetailsService.class、AuthenticationManagerResolver.class、实例
默认情况下都会满足,此时Spring Security会提供一个 InMemoryUserDetailManager 实例
这就是默认生成 user 以及 uuid 密码过程! 另外看明白源码之后,就知道只要在配置文件中加入如下配置可以对内存中用户和密码进行覆盖。
spring.security.user.name=root
spring.security.user.password=root
spring.security.user.roles=admin,users
记:
- WebSecurityConfigurerAdapter 扩展 Spring Security 所有默认配置
- UserDetailService 用来修改默认认证的数据源信息
自定义认证
自定义资源权限规则
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
http
.authorizeRequests() // 配置请求的访问控制
.antMatchers("/index").permitAll() // /index路径允许所有用户访问(包括未认证的用户)
.antMatchers("/admin").hasRole("admin") // /admin路径只允许具有admin角色的用户访问
.anyRequest().authenticated() // 所有其他请求都需要身份验证
.and() // 用于连接其他配置部分
.formLogin() // 启用默认的表单登录
.loginPage("/login") // 可选:自定义登录页面URL
.permitAll()
.and()
.rememberMe() // 启用记住我功能
.key("uniqueAndSecret"); // 设置一个唯一且秘密的键,用于生成“记住我”cookie
}
}
注意!配置项的先后顺序很重要
以下是几个常见配置项及其顺序的影响:
- antMatchers()的顺序:
-
Spring Security会按照配置顺序检查antMatchers(),并应用第一个匹配的规则。因此,特定路径的规则应放在更通用规则之前。
例如,特定的路径如/admin应该在更通用的路径/**之前配置。
- authorizeRequests()与formLogin()和logout()的顺序:
- 通常,你会先配置authorizeRequests(),因为这是定义哪些请求需要认证的地方。
- formLogin()和logout()通常放在最后,因为这些是处理身份验证和注销的配置。
为什么顺序重要
- 匹配顺序:Spring Security按照配置顺序检查每个请求,并应用第一个匹配的规则。如果通用路径配置在特定路径配置之前,会导致特定路径配置失效。
例如,如果你将antMatchers(“/**”).authenticated()放在antMatchers(“/admin”).hasRole(“admin”)之前,那么/admin路径将匹配到通用的authenticated()规则,而不是hasRole(“admin”)规则。 - 覆盖关系:更具体的规则应该在前面,这样它们不会被更通用的规则覆盖。
实践中的顺序
- 特定路径规则:总是放在最前面。
例如,antMatchers(“/admin”).hasRole(“admin”)。 - 公开路径规则:放在中间。
例如,antMatchers(“/public/**”).permitAll()。 - 通用路径规则:放在最后。
例如,antMatchers(“/**”).authenticated()。 - 其他功能配置:如formLogin()和logout()等配置通常放在路径规则之后。
配置项详细说明:
- antMatchers(“/admin”).hasRole(“admin”):
- 这一行配置了/admin路径需要具有admin角色的用户才能访问。
- 由于这是一个特定路径,放在配置的最前面。
- antMatchers(“/public/**”).permitAll():
- 这一行配置了所有/public路径下的资源都允许所有用户访问,不需要任何认证。
- 由于这是一个较具体的公开路径,放在第二。
- antMatchers(“/**”).authenticated():
- 这一行配置了所有其他路径都需要认证(登录)才能访问。
- 这是一个通用的路径配置,放在最后确保所有未明确配置的路径都需要认证。
- formLogin():
- 配置了表单登录,包括自定义登录页面。
- permitAll()允许所有用户访问登录页面,即使是未认证用户。
- logout():
- 配置了注销功能,并允许所有用户访问注销URL。
- .loginProcessingUrl(“/doLogin”):
- 配置用于指定处理登录请求的URL。当用户提交登录表单时,表单的action属性应该指向这个URL。
- Spring Security将拦截这个URL的请求,处理用户提交的凭证(用户名和密码),并进行身份验证。
原文地址:https://blog.csdn.net/yayaye717/article/details/140308752
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!