Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。它是用于保护基于 Spring 的应用程序。
Spring Security 是一个框架,侧重于为 Java 应用程序提供身份验证和授权。与所有 Spring 项目一样,Spring 安全性的真正强大之处,在于它很容易扩展以满足定制需求。
一个简单的spring security例子
spring:
# Spring Security 配置项,对应 SecurityProperties 配置类
security:
# 配置默认的 InMemoryUserDetailsManager 的用户账号与密码。
user:
name: user # 账号
password: user # 密码
roles: ADMIN # 拥有角色
# 在 spring.security 配置项,设置 Spring Security 的配置,对应 SecurityProperties 配置类。
#默认情况下,Spring Boot UserDetailsServiceAutoConfiguration 自动化配置类,
#会创建一个内存级别的 InMemoryUserDetailsManager Bean 对象,提供认证的用户信息。
#这里,我们添加了 spring.security.user 配置项,UserDetailsServiceAutoConfiguration 会基于配置的信息创建一个用户 User 在内存中。
#如果,我们未添加 spring.security.user 配置项,UserDetailsServiceAutoConfiguration 会自动创建一个用户名为 "user" ,
#密码为 UUID 随机的用户 User 在内存中。
config类
/**
* @Author peppers
* 继承 WebSecurityConfigurerAdapter 抽象类,实现 Spring Security 在 Web 场景下的自定义配置
*
*
* 我们可以重写WebSecurityConfigurerAdapter的方法,实现自定义的spring security的配置
**/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启对 Spring Security 注解的方法,进行权限验证
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**重写 #configure(AuthenticationManagerBuilder auth) 方法,实现 AuthenticationManager 认证管理器。*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth
//使用内存中的InmemortUserDetailsManager
//Spring 内置了两种 UserDetailsManager 实现:
//1.InMemoryUserDetailsManager
//2.JdbcUserDetailsManager ,基于 JDBC的 JdbcUserDetailsManager 。
//实际项目中,我们更多采用调用 AuthenticationManagerBuilder#userDetailsService(userDetailsService) 方法,
// 使用自定义实现的 UserDetailsService 实现类,更加灵活且自由的实现认证的用户信息的读取。
.inMemoryAuthentication()
//不使用PasswordEncoder密码编码器
.passwordEncoder(NoOpPasswordEncoder.getInstance())
//配置admin用户
.withUser("admin").password("admin").roles("NORMAL")
//篇日志normal用户
.and().withUser("normal").password("normal").roles("NORMAL");
}
/**重写 #configure(HttpSecurity http) 方法,主要配置 URL 的权限控制*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//配置请求地址的全限,开始配置 URL 的权限控制
/**#(String... antPatterns) 方法,配置匹配的 URL 地址,基于 Ant 风格路径表达式 ,可传入多个。
【常用】#permitAll() 方法,所有用户可访问。
【常用】#denyAll() 方法,所有用户不可访问。
【常用】#authenticated() 方法,登录用户可访问。
#anonymous() 方法,无需登录,即匿名用户可访问。
#rememberMe() 方法,通过 remember me 登录的用户可访问。
#fullyAuthenticated() 方法,非 remember me 登录的用户可访问。
#hasIpAddress(String ipaddressExpression) 方法,来自指定 IP 表达式的用户可访问。
【常用】#hasRole(String role) 方法, 拥有指定角色的用户可访问。
【常用】#hasAnyRole(String... roles) 方法,拥有指定任一角色的用户可访问。
【常用】#hasAuthority(String authority) 方法,拥有指定权限(authority)的用户可访问。
【常用】#hasAuthority(String... authorities) 方法,拥有指定任一权限(authority)的用户可访问。
【最牛】#access(String attribute) 方法,当 Spring EL 表达式的执行结果为 true 时,可以访问。*/
.authorizeRequests()
//所有用户可访问
.antMatchers("/test/echo").permitAll()
//需要admin角色
.antMatchers("/test/admin").hasRole("ADMIN")
//需要normal角色
.antMatchers("test/normal").access("hasRole('ROLE_NORMAL')")
/**配置了 .anyRequest().authenticated() ,任何请求,访问的用户都需要经过认证。*/
// .anyRequest().authenticated()
.and()
//设置Form表单登录
.formLogin()
//登录URL地址
.loginPage("/login")
.permitAll() //所有用户可访问
.and()
//配置退出相关
.logout()
//退出URL地址
.logoutUrl("/logout")
.permitAll(); //所有用户可访问
}
}
测试类
@RestController
@RequestMapping("/demo")
public class DemoController {
/**@PermitAll 注解,等价于 #permitAll() 方法,所有用户可访问。
SecurityConfig」中,配置了 .anyRequest().authenticated() ,任何请求,访问的用户都需要经过认证。所以这里 @PermitAll 注解实际是不生效的。
也就是说,Java Config 配置的权限,和注解配置的权限,两者是叠加的。*/
@PermitAll
@GetMapping("/echo")
public String demo() {
return "示例返回";
}
@GetMapping("/home")
public String home() {
return "我是首页";
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/admin")
public String admin() {
return "我是管理员";
}
@PreAuthorize("hasRole('ROLE_NORMAL')")
@GetMapping("/normal")
public String normal() {
return "我是普通用户";
}
}