1.jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2 .application里面改密码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
3 . config(基础版 在内存中)
package com.aaa.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* AuthenticationManagerBuilder 认证管理器的构建者
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//UserDeatils
UserDetails user = User.withDefaultPasswordEncoder() //默认不支持明文密码 -> 加密 使用默认的加密方式
.username("test") //用户名
.password("123456") //密码
.roles("USER")
.build(); //构建
auth.inMemoryAuthentication() //将用户信息存放到内存里面
.withUser(user); //存放的 user
}
}
//另一种方式
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 创建密码解析器
BCryptPasswordEncoder pe =new BCryptPasswordEncoder();
// 对密码进行加密
String password = pe.encode("123456");
auth.inMemoryAuthentication()
.passwordEncoder(pe) //默认没有,需要手动设置BCryptPasswordEncoder 加密 ->对比(并非解密,仅对比加密结果)
.withUser("test")
.password(password)
.roles("USER")
;
}
4 . 自定义登录页面
static包下写login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/userlogin" method="post">
用户名:<input type="text" name="username">
<br/>
用户名:<input type="password" name="password">
<br/>
<input type="submit" value="login">
</form>
</body>
</html>
config里面配置放行
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置 登录form表单
//路径的前面,必须加 /
http.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/userlogin"); //提交路径
http.authorizeRequests().antMatchers("/login.html","/userlogin","/").permitAll();//代表放行"/login.html","/userlogin","/"
//其他都需要拦截
http.authorizeRequests().anyRequest().authenticated();
// csrf 方便HTML文件通过
http.csrf().disable();
}
提交以下三点都应相同
配置参数的名字
Login.html中 为什么用户名的name要写成username
如果不想使用原来的username参数
Html中:
访问的路径/test
认证成功之后跳转到的路径就是test
从login.html进行登录的时候 登录成功才会跳转到/success路径里面
配置一个角色放行
配置一个放行拦截
http.authorizeRequests().antMatchers("/test").hasRole("USER");
配置一个角色
auth.inMemoryAuthentication()
.passwordEncoder(pe) //默认没有,需要手动设置BCryptPasswordEncoder 加密 ->对比(并非解密,仅对比加密结果)
.withUser("test2")
.password(password)
.roles("ADMIN")
;
显示无权限
配置一个资源放行
此时test2可以通行,test显示权限不足403
// http.authorizeRequests().antMatchers("/test").hasRole("USER");
//现在test2 有testpath资源 ,test没有
http.authorizeRequests().antMatchers("/test").hasAuthority("testpath");
//(List<? extends GrantedAuthority> authorities) {
// this.user.authorities(authorities);
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("testpath"));
auth.inMemoryAuthentication()
.passwordEncoder(pe) //默认没有,需要手动设置BCryptPasswordEncoder 加密 ->对比(并非解密,仅对比加密结果)
.withUser("test2")
.password(password)
.roles("ADMIN")
.authorities(authorities)//所有的资源的信息 包含角色 ,菜单
;
配置资源信息的时候角色一定是以ROLE_为开始的
3.8 注解的使用
使用注解前需要在启动器或配置类上添加注解:
@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled = true,jsr250Enabled=true)
@Secured:判断是否具有角色:
@Secured({"ROLE_admin"})
@RequestMapping("testSecured")
public String testSecured() {
return "testSecured";
}
注意:使用这个这个注解的时候对应的角色信息必须是以ROLE_**的形式出现,否则无法识别
运行结果:
@RolesAllowed:判断是否具有角色:
@RolesAllowed({"ADMIN"})
@RequestMapping("testSecured")
public String testSecured() {
return "testSecured";
}
注意:此注解不需要特别添加前缀ROLE_
@PreAuthorize:进入方法前进行权限验证, @PreAuthorize 可以将登录用户的 权限参数传到方法中。
@RequestMapping("/preAuthorize")
//@PreAuthorize("hasRole('ROLE_ADMIN')")
@PreAuthorize("hasAnyAuthority('findAll')")
public String preAuthorize(){
System.out.println("preAuthorize");
return "preAuthorize";
}
@PostAuthorize:方法执行后再进行权限验证,适合验证带有返回值的权限:
获取用户的认证的信息(三种方式)
@RestController
public class UserController {
@GetMapping("user1")
public Object getUser(Principal principal){
return principal;
}
@GetMapping("user2")
public Object getUser2(Authentication authentication){
return authentication;
}
@GetMapping("user3")
public Object getUser3(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authentication;
}
}