用户内存/jdbc存储
-
pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
sql
org/springframework/security/core/userdetails/jdbc/users.ddlcreate table users(username varchar(50) not null primary key,password varchar(500) not null,enabled boolean not null); create table authorities (username varchar(50) not null,authority varchar(50) not null,constraint fk_authorities_users foreign key(username) references users(username)); create unique index ix_auth_username on authorities (username,authority);
-
配置文件
spring.datasource.username=root spring.datasource.password= spring.datasource.url=jdbc:mysql://sql.tencentcdb.com:3333/dbname?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
-
配置类
@Autowired DataSource dataSource; @Bean public UserDetailsService userDetailsService(){ JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource); manager.createUser(User.withUsername("lisi").password(new BCryptPasswordEncoder().encode("123")).roles("admin","user").build()); return manager; }
Security中的UserDetails与数据库中的字段
忽略静态请求
-
第1阶段拦截到请求,在1阶段配好了就不会进第2阶段;
@Override public void configure(WebSecurity web) throws Exception { // 不需要登录就可以访问的资源 web.ignoring().antMatchers("/img/**","/js/**"); // super.configure(web); }
-
过了第1阶段,进入第2阶段权限认证时候不过滤;
JDBC用户存储
- 查询用户但是不知道密码
- 权限校验器
如何使用mybatis/jpa查询用户
自定义用户权限校验
Remember Me功能实现
http.
// 哪些 地址需要登录
authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.and()
.csrf().disable()
- cookie和session时间加长 / 记住我remember-me框架的
同一用户多地点登录/禁止其他终端登录
此配置和记住我有冲突
- 实现方案:
登录了把用户名和sessionid放在一个map里,有新登录就更新sessionid;
踢掉其他已登录的用户
http.
// 哪些 地址需要登录
authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf().disable()
.sessionManagement()
.maximumSessions(1);
禁止其他终端登录
http.
// 哪些 地址需要登录
authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf().disable()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
及时清理过期session
@Bean
HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
SpringSecurity防火墙与SQL注入
实现注销登录
SpringSecurity退出控制器/登录成功、失败 控制器
Ant风格路径表达式
通配符 | 说明 |
---|---|
? | 匹配任何单字符 |
* | 匹配0或者任意数量的字符 |
** | 匹配0或者更多的目录 |
例子
URL路径 | 说明 |
---|---|
/app/*.x | 匹配(Matches)所有在app路径下的.x文件 |
/app/p?ttern | 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern |
/**/example | 匹配(Matches) /app/example, /app/foo/example, 和 /example |
/app/**/dir/file.* | 匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java |
/**/*.jsp | 匹配(Matches)任何的.jsp 文件 |
最长匹配原则
最长匹配原则(has more characters)
说明,URL请求/app/dir/file.jsp,现在存在两个路径匹配模式/**/.jsp和/app/dir/.jsp,那么会根据模式/app/dir/*.jsp来匹配
匹配顺序
security像shiro一样,权限匹配有顺序,比如不能把.anyRequest().authenticated()写在其他规则前面
基于角色的权限控制与继承
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl impl = new RoleHierarchyImpl();
impl.setHierarchy("ROLE_admin > ROLE_user");
return impl;
}