1.SpringSecurity 框架用法简介
用户登录系统时我们协助 SpringSecurity 把用户对应的角色、权限组装好,同时把各个资源所要求的权限信息设定好,剩下的“登录验证”、“权限验证”等等工作都交给SpringSecurity。
2. 权限管理过程中的相关概念
2.1 主体
英文单词:principal 使用系统的用户或设备或从其他系统远程登录的用户等等。简单说就是谁使用系统谁就是主体。
2.2 认证
英文单词:authentication 权限管理系统确认一个主体的身份,允许主体进入系统。简单说就是“主体”证明自己是谁。 笼统的认为就是以前所做的登录操作。
2.3 授权
英文单词:authorization
将操作系统的“权力”“授予”“主体”,这样主体就具备了操作系统中特定功能的能力。 所以简单来说,授权就是给用户分配权限。
3. 权限管理的主流框架
3.1 SpringSecurity
SpringSecurity 特点:
- 和 Spring 无缝整合。
- 全面的权限控制。
- 专门为 Web 开发而设计。
- 旧版本不能脱离 Web 环境使用。
- 新版本对整个框架进行了分层抽取,分成了核心模块和Web 模块。单独引入核心模块就可以脱离 Web 环境。
- 重量级。
3.2 Shiro
特点:
- 轻量级。Shiro 主张的理念是把复杂的事情变简单。针对对性能有更高要求的互联网应用有更好表现。
- 通用性。
- 好处:不局限于 Web 环境,可以脱离 Web 环境使用。
- 缺陷:在 Web 环境下一些特定的需求需要手动编写代码定制。
4. 使用配置类代替XML 配置文件
4.1 @Configuration 注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
@Documented
@Component//由于当前注解带有@Component 注解,所以标记当前注解的类可以享受包的自动扫描
public @interface Configuration {
/**
* Explicitly specify the name of the Spring bean definition associated
* with this Configuration class. If left unspecified (the common case),
* a bean name will be automatically generated.
* *
The custom name applies only if the Configuration class is picked up via * component scanning or supplied directly to a {@linkAnnotationConfigApplicationContext}. * If the Configuration class is registered as a traditional XML bean definition, * the name/id of the bean element will take precedence. * * @return the specified bean name, if any * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator */
String value() default ""; }
类标记了这个注解就可以使用这个类代替 Spring 的 XML 配置文件。
4.2 @Bean 注解
用来代替 XML 配置文件中的 bean 标签。下面两种形式效果一致:
@Configuration public class AnnotaionConfig{
@Bean public EmpHandler getEmpHandler(){
return new EmpHandler();
}
}
提示:Spring 通过调用标记了@Bean 注解的方法将对象放入IOC 容器行为不会重复调用方法。原因是 Spring 想要获取 bean 对应的实例对象时会查看IOC 容器中是否已经有了这个对象,如果有则不会执行这个方法,从而保证这个 bean 是单一实例的。如果希望对应的 bean 是多实例的,则可以配合@Scope 注解。
5. 了解:_csrf 如何防止跨站请求伪造?
Cross-site request forgery 跨站请求伪造 发送登录请求时没有携带_csrf 值,则返回下面错误:
从钓鱼网站的页面提交的请求无法携带正确、被承认的令牌。
6. SpringSecurity 操作实验
实验 5:基于角色或权限进行访问
通过 HttpSecurity 对象设置资源的角色
@Override
protected void configure(HttpSecurity security) throws Exception {
security
.authorizeRequests() // 对请求进行授权
.antMatchers("/index.jsp") // 针对/index.jsp路径进行授权
.permitAll() // 可以无条件访问
.antMatchers("/layui/**") // 针对/layui目录下所有资源进行授权
.permitAll() // 可以无条件访问
.antMatchers("/level1/**") // 针对/level1/**路径设置访问要求
.hasRole("学徒") // 要求用户具备“学徒”角色才可以访问
.antMatchers("/level2/**") // 针对/level2/**路径设置访问要求
.hasAuthority("内门弟子") // 要求用户具备“内门弟子”权限才可以访问
.and()
.authorizeRequests() // 对请求进行授权
.anyRequest() // 任意请求
.authenticated() // 需要登录以后才可以访问
.and()
.formLogin() // 使用表单形式登录
// 关于loginPage()方法的特殊说明
// 指定登录页的同时会影响到:“提交登录表单的地址”、“退出登录地址”、“登录失败地址”
// /index.jsp GET - the login form 去登录页面
// /index.jsp POST - process the credentials and if valid authenticate the user 提交登录表单
// /index.jsp?error GET - redirect here for failed authentication attempts 登录失败
// /index.jsp?logout GET - redirect here after successfully logging out 退出登录
.loginPage("/index.jsp") // 指定登录页面(如果没有指定会访问SpringSecurity自带的登录页)
// loginProcessingUrl()方法指定了登录地址,就会覆盖loginPage()方法中设置的默认值/index.jsp POST
.loginProcessingUrl("/do/login.html") // 指定提交登录表单的地址
.usernameParameter("loginAcct") // 定制登录账号的请求参数名
.passwordParameter("userPswd") // 定制登录密码的请求参数名
.defaultSuccessUrl("/main.html") // 登录成功后前往的地址
// .and()
// .csrf()
// .disable() // 禁用CSRF功能
.and()
.logout() // 开启退出功能
.logoutUrl("/do/logout.html") // 指定处理退出请求的URL地址
.logoutSuccessUrl("/index.jsp") // 退出成功后前往的地址
;
}
通过 AuthenticationManagerBuilder 对象设置用户登录时具备的角色
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder
.inMemoryAuthentication() // 在内存中完成账号、密码的检查
.withUser("tom") // 指定账号
.password("123123") // 指定密码
.roles("ADMIN","学徒") // 指定当前用户的角色
.and()
.withUser("jerry") // 指定账号
.password("123123") // 指定密码
.authorities("UPDATE","内门弟子") // 指定当前用户的权限
;
}
注意:调用顺序
蓝色代码设置范围更大
红色代码设置范围相对小
如果蓝色代码先调用,会把后面红色代码的设置覆盖,导致红色代码无效。所以要 先做具体小范围设置,再做大范围模糊设置。
7. SpringSecurity 操作实验
密码加密
带盐值的加密
概念
借用生活中烹饪时加盐值不同,菜肴的味道不同这个现象,在加密时每次使用一个随机生成的盐值,让加密结果不固定