SpringSecurity

108 阅读5分钟

1.SpringSecurity 框架用法简介

image.png 用户登录系统时我们协助 SpringSecurity 把用户对应的角色、权限组装好,同时把各个资源所要求的权限信息设定好,剩下的“登录验证”、“权限验证”等等工作都交给SpringSecurity。

2. 权限管理过程中的相关概念

2.1 主体

英文单词:principal 使用系统的用户或设备或从其他系统远程登录的用户等等。简单说就是谁使用系统谁就是主体。

2.2 认证

英文单词:authentication 权限管理系统确认一个主体的身份,允许主体进入系统。简单说就是“主体”证明自己是谁。 笼统的认为就是以前所做的登录操作。

2.3 授权

英文单词:authorization

将操作系统的“权力”“授予”“主体”,这样主体就具备了操作系统中特定功能的能力。 所以简单来说,授权就是给用户分配权限。

image.png

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 值,则返回下面错误: image.png 从钓鱼网站的页面提交的请求无法携带正确、被承认的令牌。

image.png

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","内门弟子")     // 指定当前用户的权限
      ;
   
}

注意:调用顺序

image.png 蓝色代码设置范围更大

红色代码设置范围相对小

如果蓝色代码先调用,会把后面红色代码的设置覆盖,导致红色代码无效。所以要 先做具体小范围设置,再做大范围模糊设置。

image.png

7. SpringSecurity 操作实验

密码加密

带盐值的加密

概念

借用生活中烹饪时加盐值不同,菜肴的味道不同这个现象,在加密时每次使用一个随机生成的盐值,让加密结果不固定