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裏面的方法處理先後的判斷

博文是做者本來在其餘平臺的,現遷移過來

相關文章
相關標籤/搜索