1、spring security入门
idea + springboot + spring security 依赖
2、搭建步骤
- pom文件加入依赖:springboot最方便就是,需要什么就直接加入依赖即可,无需配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
idea创建项目,加入以上依赖之后,那么整个项目就被 spring security 这个安全框架接管了,现在访问任何接口都需要权限
3. 启动项目
- 编写接口
@RestController
@RequestMapping("/loginController")
public class LoginController {
@RequestMapping("/hello")
public String loginTest(){
return "hello spring security";
}
}
- 浏览器访问接口:http://localhost:8080/loginController/hello
浏览器地址会自动跳转为 http://localhost:8080/login,
这是因为没有权限,所以会自动跳转到spring security框架自带的登录页面,需要你登录,默认用户名 user ,密码后台随机自动生成的,如下图表示:c1e6e20e-d142-475e-9e2d-50fb4bd11263
登录成功:
4. spring security说明
spring security中有一个很重要的接口: UserDetailsService;当系统什么也没有配置的时候,账号和密码都是由 spring security定义生成的。但是在实际项目中账号和密码都是存放在数据库中。所以一般都需要用户自定义逻辑控制认证逻辑。
当用户需要自定义逻辑的时候,用户只需要实现 UserDetailService 接口即可
接口中方法:返回 UserDetails
// 表单提交
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
// 表示获取登录用户所有权限
Collection<? extends GrantedAuthority> getAuthorities();
// 表示获取密码
String getPassword();
// 表示获取用户名
String getUsername();
// 表示判断账户是否过期
boolean isAccountNonExpired();
// 表示判断账户是否被锁定
boolean isAccountNonLocked();
// 表示凭证{密码}是否过期
boolean isCredentialsNonExpired();
// 表示当前用户是否可用
boolean isEnabled();
5. spring security web权限的几种方案
- 方案一:通过配置文件设置登录的用户名 密码(放弃spring security自动生成),实现步骤如下:
- 配置文件设置用户名和密码: application.properties
spring.security.user.name=admin spring.security.user.password=123456
- 启动项目,请求接口
可以看到,系统此时没有生成 随机登录密码
浏览器访问:用户名 admin 密码: 123456,登录成功
- 方案二:编写类的实现接口: 实现 UserDetailsService 接口
/**
* 自定义逻辑控制:实现 UserDetailsService接口,重写 loadUserByUsername方法
*/
// 加上此注解,表示此类为一个配置类,让系统走此逻辑
@Configuration
public class MyUserDetailsServiceConfig implements UserDetailsService {
// spring security的加密方式
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (!"admin".equalsIgnoreCase(username)){
throw new UsernameNotFoundException("用户不存在");
}
List<GrantedAuthority> list = new ArrayList<>();
list.add(new SimpleGrantedAuthority("admin"));
return new User(username, passwordEncoder().encode("123456"), list);
}
}
说明:
- PasswordEncoder :spring security推荐的加密方式
- username:登录表单框内输入的用户名
- 最终返回一个 User,里面包含 用户名 和 加密后的密码 还有这个用户的权限
- 方案三:通过数据库请求验证用户名和密码,此处和方案二中代码基本没有什么区别,稍微需要修改的就是
- pom 文件中加入 数据库连接的驱动
- pom 文件中加入数据库的连接池 数据源
- 配置文件中加入连接:连接数据库的账号密码等
- 通过 service 查询用户名,比较
6. Spring Security中静态资源类 WebSecurityConfigurerAdapter
public class MyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
继承该类,重写 configure 方法,此方法种可以配置很多有关于界面交互所需的方法,如下
// 配置认证
http.formLogin() .loginPage("/index") // 配置哪个url为登录页面
.loginProcessingUrl("/login") // 设置哪个是登录的url。
.successForwardUrl("/success") // 登录成功之后跳转到哪个url
.failureForwardUrl("/fail"); // 登录失败之后跳转到哪个url
http.authorizeRequests()
.antMatchers("/layui/**","/index") //表示配置请求路径
.permitAll() // 指定URL无需保护。
.anyRequest() // 其他请求
.authenticated(); //需要认证
// 关闭csrf
http.csrf().disable();
其它的方法:比如 判断是否有权限请求,获取表单的用户名和密码等等
7. hasRole hasAuthority
注意: 若通过 spring security 给用户授用户角色的话,必须要记住一点的是 角色之前要带 ROLE_
底层源码截图:
给用户添加角色:
8. 注解: @Secured : 判断是否具有角色,匹配的字符串需要添加前缀“ROLE_“
注:若要使用spring security的注解,必须先开启注解功能
- 首先在springboot的启动类上加开启注解的功能 @EnableGlobalMethodSecurity(securedEnabled=true)
@SpringBootApplication
// 加上此注解,开启全局注解功能
@EnableGlobalMethodSecurity(securedEnabled=true)
public class DemosecurityApplication {
public static void main(String[] args) {
SpringApplication.run(DemosecurityApplication.class, args);
}
}
- 在控制器方法上添加注解:这里匹配的字符串需要添加前缀“ROLE_“
// 测试注解:
@RequestMapping("testSecured")
@ResponseBody
@Secured({"ROLE_normal","ROLE_admin"})
public String helloUser() {
return "hello,user";
}