登录认证-Security
一.传统认证
用户登录流程原理
登录基本流程
用户发起登录请求——》LoginController响应请求拿到用户输入的账户密码——》调用Service层通过Dao层根据用户名从数据库查找用户对象——》service层对用户输入的信息和数据库查询的用户对象比较——》认证成功,通过UserContext用户上下文将用户对象信息保存到session
登录详细流程
service层判断输入信息是否为空——》
根据用户名调用mapper层到数据库中查询——》
判断查询对象对象是否为空,判断查询对象密码是否和用户输入密码相同(注意MD5加密顺序)——》
认证成功,根据用户id调用mapper查询permission权限表,将用户权限设置到user对象中返回
将user对象保存到session中,此时session中就有用户的登录信息和权限信息
UserContext工具
UserContext工具可以获取session进而操作
认证流程
创建一个拦截器LoginCheckInterceptor拦截用户登录请求——》
从UserContext中获取session判断是否有User登录对象,如果不存在,表示没有登录,跳转到登录页面
如果存在,放行
传统授权
创建拦截器PermissionCheckInterceptor拦截用户访问方法资源的请求——》
通过UserContext获取用户对象进而获取用户的权限集合permissionList——》
调用方法获取访问方法需要的权限——》
遍历用户权限集合permissionList,比对是否含有方法需要的权限——》
如果没有,不允许访问
二.Security认证
基本词汇
Authorization :授权
Authentication :认证(登录)
WebSecurityConfigurerAdapter : web安全配置类(认证授权配置)
@EnableWebSecurity :开启web安全配置
HttpSecurity : http安全配置
permitAll : 放行
antMatchers : 用来匹配某些url路径 : antMatchers(“/login”).permitAll();
UserDetailsService :用户详情服务(用来加载数据库的用户数据) UserDao , UserMapper
SecurityContext : Security上下文工具,保存得有认证成功之后的用户信息
认证授权底层原理
Security认证是基于Filter实现认证和授权的,底层通过FilterChainProxy调用Filter链,Filter通过调用AuthenticationManager认证管理器实现认证,调用AccessDecisionManager授权决策器实现授权
SpringBoot集成Security
1.导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.创建主启动类
@SpringBootApplication
public class ApplicationConfig {
public static void main(String[] args) {
SpringApplication.run(ApplicationConfig.class);
}
}
3.创建web控制器(刚搭建好Security后测试用的)
@Controller
public class AuthController {
//当用户登录认证成功后重定向到该地址
@RequestMapping("/loginSuccess")
@ResponseBody
public String loginSuccess(){
return "登录成功";
}
}
4.配置Security***
创建一个配置类WebSecurityConfig继承WebSecurityConfigurerAdapter,主要做三个自定义配置
4.1配置UserDetailService(JDBCUserDetailService.java)
创建一个service实现UserDetailService接口并复写方法
- 从数据库查询用户信息
- 查询权限信息
- 封装UserDetail返回
4.2配置密码编码器(WebSecurityConfig.java)
设置密码编码器
4.3配置授权规则(WebSecurityConfig.java)
设置放行的访问路径
设置登录的自定义页面
设置登录的表单提交请求
…
@Configuration //添加注解表明是一个配置类
@EnableWebSecurity //开启webSecurity安全认证
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//提供用户信息,这里没有从数据库查询用户信息,在内存中模拟
@Bean
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager inMemoryUserDetailsManager =
new InMemoryUserDetailsManager();
inMemoryUserDetailsManager.createUser(User.withUsername("zs").password("123").authorities("admin").build());
return inMemoryUserDetailsManager;
}
//密码编码器:不加密
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
//授权规则配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() //授权配置
.antMatchers("/login","/loginout").permitAll() //登录路径和登出放行
.anyRequest().authenticated() //其他路径都要认证之后才能访问
.and().formLogin() //允许表单登录
.successForwardUrl("/loginSuccess") // 设置登陆成功页
.and().logout().permitAll() //登出路径放行 /logout
.and().csrf().disable(); //关闭跨域伪造检查
}
}