目录
一、设置登录系统的账号、密码
二、数据库查询用户名密码
三、自定义登录页面
四、基于角色或权限进行访问控制
(一)hasAuthority 方法
(二)hasAnyAuthority 方法
(三)hasRole 方法
(四)hasAnyRole
五、自定义403页面
六、注解使用
(一)@Secured
(二)@PreAuthorize
(三)@PostAuthorize
(四)@PreFilter
(五)@PostFilter
七、基于数据库的记住我
八、CSRF
一、设置登录系统的账号、密码
方式一,配置文件application.properties
spring.security.user.name=lucy
spring.security.user.password=123
方式二,编写配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String password = bCryptPasswordEncoder.encode("123");
auth.inMemoryAuthentication().withUser("zhangsan").password(password).roles("admin");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
方式三,通过类实现接口UserDetailService
@Service
public class userDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException
List list = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User("zhangsan", new BCryptPasswordEncoder().encode("123"), list);
}
}
二、数据库查询用户名密码
引入依赖
org.projectlombok
lombok
mysql
mysql-connector-java
com.baomidou
mybatis-plus-boot-starter
3.0.5
建表sql
create table users(
id bigint primary key auto_increment,
username varchar(20) unique not null,
password varchar(100)
);
数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone= GMT%2B8
username: root
password: 123456
实体类users
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Users {
private Integer id;
private String username;
private String password;
}
mapper
@Mapper
public interface UserMapper extends BaseMapper {
}
修改userDetailService
@Service
public class userDetailsService implements UserDetailsService {
@Autowired
UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
// 使用mapper查询数据库
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("username", s);
Users users = userMapper.selectOne(queryWrapper);
if (users == null) {
throw new UsernameNotFoundException("用户名不存在!");
}
List list = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()), list);
}
}
修改SecurityConfigTest
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
三、自定义登录页面
在配置类SpringSecurity中重写configure方法
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() //自定义自己编写的登录页面
.loginPage("/login.html") //登录页面设置
.loginProcessingUrl("/user/login") //登录访问路径
.defaultSuccessUrl("/test/index").permitAll() //登录成功之后,跳转路径
.and().authorizeRequests()
.antMatchers("/", "/test/hello","/user/login").permitAll() // 设置哪些路径可以直接访问,不需要认证
.anyRequest().authenticated()
.and().csrf().disable(); // 关闭csrf防护
}
再编写登录页面
Title
用户名:
密码:
controlller
@RestController
@RequestMapping("/test")
public class HelloController {
@GetMapping("/hello")
public String test() {
return "hello, security";
}
@GetMapping("/index")
public String index() {
return "hello, index";
}
}
启动项目后使用的登录页面就是我们编写的 了
四、基于角色或权限进行访问控制
(一)hasAuthority 方法
如果当前的主体具有指定的权限,则返回 true,否则返回 false
设置访问/test/index需要admin角色
给用户添加admin角色
修改角色为别的,不是admin后访问被禁止
(二)hasAnyAuthority 方法
(三)hasRole 方法
,
否则出现
403
。
。
底层源码:
给用户添加角色需要加上前缀ROLE_
ROLE_
“,因为上述的底层代码会自动添加与之进行匹配。
(四)hasAnyRole
修改配置文件:
五、自定义403页面
在配置类中配置
编写unauth页面
Title
没有访问权限
跳转成功
六、注解使用
(一)@Secured
ROLE_
“。
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled=true)
public class DemosecurityApplication {
public static void main(String[] args) {
SpringApplication.run(DemosecurityApplication.class, args);
}
}
controller
@GetMapping("/update")
@Secured({"ROLE_admin"})
public String update() {
return "hello, update";
}
(二)@PreAuthorize
(prePostEnabled =
true
)
@GetMapping("/update")
@PreAuthorize("hasAnyAuthority('admin')")
public String update() {
return "hello, update";
}
(三)@PostAuthorize
(prePostEnabled =
true
)
注解使用并不多,在方法执行后再进行权限验证,适合验证带有返回值的权限.
@RequestMapping("/testPostAuthorize")
@ResponseBody
@PostAuthorize("hasAnyAuthority('admin')")
public String preAuthorize(){
System.out.println("test--PostAuthorize");
return "PostAuthorize";
}
(四)@PreFilter
进入控制器之前对数据进行过滤
@RequestMapping("getTestPreFilter")
@PreAuthorize("hasRole('ROLE_管理员')")
@PreFilter(value = "filterObject.id%2==0")
@ResponseBody
public List getTestPreFilter(@RequestBody List list){
list.forEach(t-> {
System.out.println(t.getId()+"t"+t.getUsername());
});
return list;
}
(五)@PostFilter
:权限验证之后对数据进行过滤 留下用户名是
admin1
的数据
filterObject
引用的是方法返回值
List
中的某一个元素
@RequestMapping("getAll")
@PreAuthorize("hasRole('ROLE_管理员')")
@PostFilter("filterObject.username == 'admin1'")
@ResponseBody
public List getAllUser(){
ArrayList list = new ArrayList();
list.add(new UserInfo(1l,"admin1","6666"));
list.add(new UserInfo(2l,"admin2","888"));
return list;
}
七、基于数据库的记住我
使用spring security记住登录的用户原理
创建表
CREATE TABLE `persistent_logins` (
`username` varchar(64) NOT NULL,
`series` varchar(64) NOT NULL,
`token` varchar(64) NOT NULL,
`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
配置文件编写数据库的配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone= GMT%2B8
username: root
password: 123456
配置类
2
周时间。但是可以通过设置状态有效时间,即使项目重新启动下次也可以正常登录。
name
属性值必须为
remember-me.
不能改为其他值
Title
用户名:
密码:
60s内免登录
八、CSRF
(英语:
Cross-site request forgery
),也被称为
one-click
attack
或者
session riding
,通常缩写为
CSRF
或者
XSRF
, 是一种挟制用户在当前已登录的 Web
应用程序上执行非本意的操作的攻击方法。跟
跨网站脚本
(
XSS
)相比,
XSS 利用的是用户对指定网站的信任,CSRF
利用的是网站对用户网页浏览器的信任。
web
中用户身份验证的一个漏洞:
简单的身份验证只能保证请求发自某个用户的浏览
器,却不能保证请求本身是用户自愿发出的
。
Spring Security 4.0
开始,默认情况下会启用
CSRF
保护,以防止
CSRF
攻击应用程序,Spring Security CSRF
会针对
PATCH
,
POST
,
PUT
和
DELETE
方法进行防护。