学习SpringSecurity-01

转自:https://www.kancloud.cn/hanxt/springsecurity/1221477
springSecurity 是 一个安全框架,他是一套集合了 认证和授权的一整套框架的。
通过简单的方式来 学习spring security
通过案例 来进行学习:转自:https://www.kancloud.cn/hanxt/springsecurity/1221477
login.html登录页面,登录页面访问不受限制
在登录页面登录之后,进入index.html首页(登录验证Authentication)
首页可以看到syslog、sysuer、biz1、biz2四个页面选项
我们希望syslog(日志管理)和sysuser(用户管理)只有admin管理员可以访问(权限管理Authorization)
biz1、biz2普通的操作用户auser就可以访问(权限管理Authorization)

首先是springsecurity 的 httpBasic 模式,这种模式 实际的应用场景有限,在真实的 项目中不存在对应的应用场景,所以不过多介绍;
http.httpBasic().and()
.authorizeRequests()//任何身份
.anyRequest()//所有请求
.authenticated();//都需要认证

主要介绍spring security 的其他几种模式:

  1. form 表单
  2. form表单添加验证码
  3. form 表单 从数据库加载用户信息
  4. form表单从数据库加载权限
  5. 短信验证码登录
  6. jwt
  7. 第三方登录
  8. 提供认证管理
    首先 准备工作:
    springboot 2.0 + spring security + mybatis +jdk1.8+fastJson

后面也会 提供对应的代码地址

我们 要知道spring security 这个框架可以为我们做什么?
spring security 主要 可以为 我们做 认证和 鉴权的功能
认证 就是 我们常说的 登录的功能,鉴权就是我们经常做的,判断某个资源,该用户能不能访问,

认证:就是给当前的登录的用户,通过某些方式,颁发一个合理的身份和对应的权限。
鉴权:通过颁发的身份,查看当前的身份能否访问具体的方法;

认证:
在spring security 中 默认提供了:
HttpBasic模式和formLogin模式 这两种的方式
而对应的模式有对应的场景.
HttpBasic模式:是在访问具体的方法前,弹出一个框,输入的对应的用户名和对应的密码,是一种很简陋的模式,此种方式因为对应的账号密码一般都是在配合文件中写死的 或者对应的在 启动时,给定的随机的账号和密码,然后请求对应的 spring security 提供的默认方法(相当于一个servlet 不过 框架自己提供),自己配置对应的权限就可以使用,很方便。对应的安全性也是很低的。
因为他的原理就很简单,假如你在服务端配置的账号和密码是为 mbb:密码为:mbb
此时 请求到后端的时候 在对应的请求头中 就会有 这样的东西 mbb:mbb(通过base64编码),此时后端接收对应的 base64编码后的数据


package com.mbb.stu.config;

import com.mbb.stu.service.MyRBACService;
import com.mbb.stu.service.MyUserDatiailServiceImpl;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

@Configurable
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)  启用 方法级别的 权限管理  可以 在 对应的方法上面 写对应的 spel表达式
//PreAuthorize注解 进入方法前的权限验证。示例: @PreAuthorize("hasRole('admin')")  只有拥有ADMIN角色才能访问findAll方法。以下注解都是方法上面的注解



//@PostAuthorize("returnObject.name == authentication.name")   @PostAuthorize 在方法执行后再进行权限验证,适合根据返回值结果进行权限验证。
// Spring EL 提供返回对象能够在表达式语言中获取返回的对象returnObject。
// 下文代码只有返回值的name等于authentication对象的name(当前登录用户名)才能正确返回,否则抛出异常

//@PreFilter(filterTarget="ids", value="filterObject%2==0")  过滤参数的注解

//@PostFilter("filterObject.name == authentication.name")  结果过滤

public class SpringSecturityFormConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private SecuritySuccessHandler securitySuccessHandler;
  @Autowired
  private SecurityFailHandler securityFailHandler;

  @Autowired
  private MyUserDatiailServiceImpl myUserDatiailService;
  @Autowired
  private  MyLogoutSuccessHandler myLogoutSuccessHandler;
  @Autowired
  private MyRBACService rbacService;
  @Autowired
  private VerificationCodeFilter verificationCodeFilter;

  @Autowired
  private SmsSpringSecurityConfig smsSpringSecurityConfig;

  @Override
  protected void configure(HttpSecurity http) throws Exception {


        http.csrf().disable()//禁用跨站csrf攻击防御
            //在对应过滤器链中,添加对应过滤器,并且指定对应的过滤器链中 过滤器的顺序
            .addFilterBefore(verificationCodeFilter, UsernamePasswordAuthenticationFilter.class)
            .formLogin() //设置为 表单登录方式
            .loginPage("/login.html")
            .loginProcessingUrl("/login")//登录表单form中action的地址,也就是处理认证请求的路径
            .passwordParameter("username")//表单中用户名的name
            .passwordParameter("password")//表单中用户密码的name
            .failureHandler(securityFailHandler) //设置自定义失败处理器
           // .failureForwardUrl("/login.html")//设置认证失败跳转链接
            //.defaultSuccessUrl("/index")//设置成功的跳转链接
            .successHandler(securitySuccessHandler)//设置自定义 成功处理器
            .and()
            .apply(smsSpringSecurityConfig)
            .and()
            .rememberMe()//开启记住我的模式
            .rememberMeParameter("remember-me")// 记住我的 复选框的 name
            .rememberMeCookieName("sss")// 记住我的 cookie name
            //.authenticationSuccessHandler()//记住我 成功的回调
            .tokenRepository(persistentTokenRepository()) //实现 数据库 记住我的 关键 注入数据源 表的结构 还有名字 已经定义好 为 固定结构
            //JdbcTokenRepositoryImpl 具体可以查看 对应的jdbc TokenRepostoryImpl 中 当然也可以 通过对应的反射 动态修改 updateTokenSql  可以自己 尝试
            .and()
            .logout() //开启 退出登录
            .logoutUrl("/logout")//退出登录后 的请求url
           // .logoutSuccessUrl("/login.html")//退出登录后 跳到的url  logoutSuccessHandler 二选一
            .deleteCookies("JSESSIONID")//删除的 cookies 的值 list
            .logoutSuccessHandler(myLogoutSuccessHandler) //退出登录 处理类 可以自定义 退出动作登录时长计算,清理业务相关的数据等等  此处理handler  和 logoutSuccessUrl 二选一
            .and()
            .authorizeRequests() //设置请求
              .antMatchers("/login.html","/login","/favicon.ico","/kaptcha","/smslogin","/smscode").permitAll() //匹配地址 为所有权限都可以访问的地址
            .antMatchers("/index.html","/index").authenticated()
            //  .antMatchers("/syslog","/sysuser").hasAnyAuthority("ROLE_admin")//匹配地址 只有 admin 权限才能 访问
           // .hasAnyRole("admin") //匹配地址 只有 admin 权限才能 访问  作用和上面相同 因为在 spring security 中 角色是一种特殊权限
            //  .antMatchers("/biz1","/biz2").hasAnyRole("admin","user")
            //db下面的资源 只能是 admin  + dba 的权限
            // .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
            //某些id  资源 只能某些用户访问
            //antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)")
            .anyRequest().access("@rbacService.hasPermission(request,authentication)") // 此处说明 方法的参数 必须为 此处的对应 而非自定义
            // access Spring El表达式  为 true 可以访问
            //anonymous() 匿名 可以访问
            //denyAll() 拒绝访问
            //fullyAuthenticated 用户 完全认证可以访问 非 rememberMe
            // hasAnyAuthority (角色也是一种特殊权限)  hasAnyRole 用户拥有某种用户才可以访问
            //hasIpAddress 用户来自 这个ip的可以访问
            //permitAll  无任何限制
            //rememberMe 允许通过 记住我 的用户访问
            //authenticated 登录才可以访问
            .and()
            .sessionManagement() //设置session 管理器
            .sessionFixation().migrateSession()
           // .migrateSession() // 设置session 每次请求都是 一个新的session  并保留所有会话属性   默认的就好 其他应用场景自己归纳
          // changeSessionId  变更会话ID并保留所有会话属性
            // 其他选项
            //none()  关闭spring security的session防护功能,spring不会配置SessionManagementFilter类;
            //migrateSession() 用户认证之后,会重新创建一个新的session,并且将旧session中的属性,迁移到新的session中;
            //newSession()用户认证之后,会新创建一个session,但是不会将旧的session中的属性,迁移到新的session中
            .maximumSessions(1) //最大用户登录数量 就是一个账号的最大登录数
            .expiredSessionStrategy(new MySessionExpiredStrategy()); //设置 session 失效的触发规则
  }


 /* @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable() //禁用跨站csrf攻击防御
        .formLogin()
        .loginPage("/login.html")//用户未登录时,访问任何资源都转跳到该路径,即登录页面
        .loginProcessingUrl("/login")//登录表单form中action的地址,也就是处理认证请求的路径
        .usernameParameter("username")///登录表单form中用户名输入框input的name名,不修改的话默认是username
        .passwordParameter("password")//form中密码输入框input的name名,不修改的话默认是password
        .defaultSuccessUrl("/index")//登录认证成功后默认转跳的路径
        .and()
        .authorizeRequests()
        .antMatchers("/login.html","/login").permitAll()//不需要通过登录验证就可以被访问的资源路径
        .antMatchers("/biz1","/biz2") //需要对外暴露的资源路径
        .hasAnyAuthority("ROLE_user","ROLE_admin")  //user角色和admin角色都可以访问
        .antMatchers("/syslog","/sysuser")
        .hasAnyRole("admin")  //admin角色可以访问
        //.antMatchers("/syslog").hasAuthority("sys:log")
        //.antMatchers("/sysuser").hasAuthority("sys:user")
        .anyRequest().authenticated();
  }*/
  @Override
  protected void configure(AuthenticationManagerBuilder bulider) throws Exception {
    bulider.userDetailsService(myUserDatiailService)
    .passwordEncoder(passwordEncoder());
  /*  bulider.inMemoryAuthentication().withUser("user")
        .password(passwordEncoder().encode("123456"))
        .roles("user")
        .and()
        .withUser("admin")
        .password(passwordEncoder().encode("123456"))
        .roles("admin")
        .and()
        .passwordEncoder(passwordEncoder());//配置BCrypt加密*/

  }

  /*public static void main(String[] args) {
    System.out.println(passwordEncoder().encode("123456"));
  }
*/
  @Bean
  public  PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
  }

  @Override
  public void configure(WebSecurity web) {
    //将项目中静态资源路径开放出来
    web.ignoring().antMatchers( "/css/**", "/fonts/**", "/img/**", "/js/**");
  }


  @Autowired
  private DataSource dataSource;//数据源 此为 对应的 配置文件中的 数据源信息

  @Bean
  public PersistentTokenRepository persistentTokenRepository(){//记住我的 实体类 注入对应的 数据源
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(dataSource);
    return tokenRepository;
  }

  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值