Spring Security简单起步(使用Spring Boot)

建立一个SpringBoot项目

  • 网址输入 start.spring.io https://start.spring.io/
  • 输入Group 和 Artifact
  • 点击下面一排小字的 Switch to the full version.
  • 勾选 Security 和 Web俩个模块
  • 如图所示:
  • 找到项目中包下的 XXXApplication的那个java类, 为它填上三个注解
//至关于三个注解,之后再讲
        @SpringBootApplication
        //至关于ResponseBody 和 Controller 
        @RestController
        //在这个类中所使用的jar包都会被加载,并且提供默认配置 excludeName能够取消默认配置
        @EnableAutoConfiguration
  • 如今在这个类里面添加一个方法
@RequestMapping("/")
        public String home(){
            return "MackyHuang First SpringBoot";
        }
  • 而后打开pom.xml,备注里面关于tomcat的代码
<!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
            <!--<scope>provided</scope>-->
        <!--</dependency>-->
  • 容许这个 XXXApplication类的main方法,咱们就会看到springboot启动啦!

关于SpringSecurity的配置与使用

  • 新建一个Config类 继承WebSecurityConfigurerAdapter,而后实现里面的三个方法,先简略的看一下代码再进行解释
@Configuration
        @EnableWebSecurity
        public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
        @Resource
        private UserServiceOwn serviceOwn;
        @Override
        protected void configure(HttpSecurity http) throws Exception {
        //容许主目录 / 的访问
        //check任何目录
        //容许注销
        //容许表单登录
        //禁用csrf
        http.authorizeRequests()
        .antMatchers("/authorize", "/").permitAll()
        .anyRequest().authenticated()
        .and()
        .logout().permitAll()
        .and()
        .formLogin();
        http.csrf().disable();
        }
        
        //容许资源文件加载
        @Override
        public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
        }
        
        //Spring Security中密码的存储格式须要加密,因此须要这种格式
        //若是再数据库中
        //须要
        //auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("macky")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("ADMIN");
        
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("huang")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("ADMIN");
        
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("user")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("USER");
        
        //auth.userDetailsService(serviceOwn).passwordEncoder(new PasswordEncoderOwn());
        ////security默认的数据库操做
        //auth.jdbcAuthentication().usersByUsernameQuery("macky").authoritiesByUsernameQuery("admin").passwordEncoder(new BCryptPasswordEncoder());
        }
        }
  • 在看完代码以及注释之后(其实注释已经说明了大量的问题)
  • 第一个类
@Override
        protected void configure(HttpSecurity http) throws Exception {
    
        http.authorizeRequests()  
        .antMatchers("/authorize", "/").permitAll()  //容许主目录 / 的访问
        .anyRequest().authenticated() //check任何目录
        .and()
        .logout().permitAll()  //容许注销
        .and()  
        .formLogin();  //容许表单登录
        http.csrf().disable();   //禁用csrf
        }
  • 这里 调用http, 进行了一系列匹配, 其中的csrf就是Cross-site request forgery跨站请求伪造
  • 第二个类
//    容许资源文件加载
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
        }
  • 这个类解决的是资源文件的,对于那些请求这些资源文件的请求进行忽略
  • 第三个类
//这里只介绍关于内存中的储存用户信息
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //Spring Security中密码的存储格式须要加密,因此须要这种格式
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("macky")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("ADMIN");
        
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("huang")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("ADMIN");
        
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("user")
        .password(new BCryptPasswordEncoder().encode("123456"))
        .roles("USER");

        。。其实以上的内容,就是内存中建立一个用户信息,指定气密码的匹配器,而后指定用户名,密码和角色,这里咱们建立了3个用户,俩个角色

        
        //auth.userDetailsService(serviceOwn).passwordEncoder(new PasswordEncoderOwn());
        ////security默认的数据库操做
        //auth.jdbcAuthentication().usersByUsernameQuery("macky").authoritiesByUsernameQuery("admin").passwordEncoder(new BCryptPasswordEncoder());
    }

搞定了用户角色层次的,如今咱们来配置一些访问的网页把(如下代码都在XXXApplication中,这里咱们实际上是把它看成是一个Controller,由于注解里面已经将它进行了配置)

@RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
  • 如今,让咱们再容许一次项目,访问主目录 / 和 /hello 俩个页面,会发现, 主目录顺利访问了,然而,那个hello页面跳转到了登录界面,这是为了啥子呢!
  • 回想咱们前面的配置,会发现,咱们在第一个config里面忽略了主目录的过滤,全部它是不须要验证的。

让咱们试试角色把

@PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping("/manage")
    public String manage(){
        return "Only admin can see this page";
    }
  • 而且!在XXXApplication类上面添加注解
@EnableGlobalMethodSecurity(prePostEnabled = true)
  • 添加了这段代码之后,继续访问,试着用不一样的帐号去登录,而后查看结果
  • 拥有ADMIN角色的用户能够顺利访问,而拥有USER的用户出现没有权限访问的页面,返回403 无权限访问
  • 很明显,一来咱们添加了俩个注解
    @PreAuthorize("hasRole('ROLE_ADMIN')")
  • 它使得咱们的方法在访问前须要进行必定的操做,而咱们在里面的参数是 hasRole,全部就是判断访问者的角色,而另一个 @EnableGlobalMethodSecurity就是使得上面的这个注解生效

让咱们了解更多一些

  • 其实相似于 @PreAuthorize 这样的注解不止这一个css

    //    这是方法进入前的判断,能够有内置的方法,也能够对参数进行判断
       @PreAuthorize("#index<10")    
       //    拦截方法调用后  这里仍是遭到了拦截
       @PostAuthorize("returnObject==2")
    
       //    若是参数或者返回值是集合的时候,就可使用*Filter注解,功能和上面的是同样的
       //    filterObject表示集合内的一个元素
       @PreFilter("filterObject<10")
       @PostFilter("filterObject<5")
  • 这俩组注解其实见文知意, 相似于AOP里面的方法处理先后的判断

博文是做者本来在其余平台的,现迁移过来

相关文章
相关标签/搜索