springboot+springsecurity+cas整合
使用spring security步驟
1、使用@EnableWebSecurity開啟spring security框架, 使用@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true)開啟基於方法的角色許可權控制, 方法許可權有三個註解: @Secured("USER") 由spring 提供 @PreAuthorize("hasRole('ADMIN') AND hanRole('USER')") 由spring提供,支援springEL表示式,優先使用 @RolesAllowed("ROLE_ADMIN") 由jsr 250 提供
2、security給我們提供了一個WebSecurityConfigurerAdapter類,該類提供了預設配置,因此我們的配置類只需要繼承該類就可以了 自定義配置需要覆寫三個方法:
第一個方法: com.hou.security.config.WebSecurityConfig.configure(AuthenticationManagerBuilder auth) throws Exception AuthenticationManagerBuilder 是AuthenticationManager物件的builder物件,可以通過該builder物件的方法構建是AuthenticationManager物件。 AuthenticationManager物件是用來認證使用者提交的認證資訊的,因此在配置的時候我們就應該先把我們儲存的使用者資訊載入到記憶體中,或者告訴可以去哪裡拿到認證資訊 因此這個方法裡面提供三種載入使用者資訊的方式: /*//一、使用記憶體使用者
//spring5中所有密碼都需要編碼器,因此不能使用明文密碼了 //roles方法會自動給設定的角色加上ROLE_的字首,比如設定角色為USER,那麼在spring security框架中的,角色為ROLE_USER //1、建立密碼編碼器,不管怎樣密碼肯定不是明文,因此需要密碼編碼器 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //2、設定使用記憶體寫入使用者資訊 auth.inMemoryAuthentication() //3、設定密碼編碼器 .passwordEncoder(passwordEncoder) //4、設定使用者 .withUser("admin") //注意改密碼一定要是密碼編碼器加密後的字串 abc .password("$2a$10$ho.HXLXWT5y0hHMkTLJcauXlHmipL/lSjT9COXPNIVUk5.XMnyTAW") .roles("ADMIN") //and起連線作用,連線下一個使用者資訊 .and() .withUser("user") //密碼123456 .password("$2a$10$11sQYFK1sLGb4D5B5oZwWeKSF1URf8dlqXU/PDe7DS7ecCdYeqVMC") .roles("USER"); */ /*//二、使用資料庫儲存使用者 注意:存在資料庫中的角色名必須加上字首ROLE_ //1、建立密碼編碼器,不管怎樣密碼肯定不是明文,因此需要密碼編碼器 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //使用資料庫認證 auth.jdbcAuthentication() //設定密碼編碼器 .passwordEncoder(passwordEncoder) //設定資料來源 .dataSource(dataSource) //設定驗證密碼的sql .usersByUsernameQuery(pwdQuery) //設定獲取角色的sql,改sql返回多條資料,該使用者會被設定多個許可權 .authoritiesByUsernameQuery(roleQuery); */ //三、自定義使用者認證服務 注意:存在資料庫中的角色名必須加上字首ROLE_ //springsecurity通過userdetailservice介面獲取使用者資訊,改介面中只有一個loadUserByUsername方法,該方法返回一個userDetail物件,該物件儲存使用者的資訊 //改方式具體實現,請看我自定義的userDetailServiceImpl類 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder);
這三種載入使用者資訊的方式最終都會生成一個Authentication物件,該物件其實就是對使用者資訊的封裝,供AuthenticationManager物件呼叫,用於認證使用者資訊。
第二個方法: com.hou.security.config.WebSecurityConfig.configure(HttpSecurity http) throws Exception 該方法就是授權方法,告訴security框架那些路徑需要被授權才可以訪問。其實就是開啟一些filter,然後對開啟的filter進行配置,需要攔截那些。注意在這裡可以 順便配置路徑物件的許可權,這裡許可權有兩種寫法: //.antMatchers("/admin").hasAnyRole("USER") 這種寫法,框架預設會幫我們加上ROLE_字首 //.antMatchers("/admin").hasAuthority("ROLE_USER")
當然,這裡我們也可以不配置角色許可權,我們可以用方法註解配置角色許可權,參考方法許可權,以及寫法
http
.authorizeRequests() //註冊FilterSecurityInterceptor
.antMatchers("/index.html").permitAll()//訪問index.html不要許可權驗證
.anyRequest().authenticated()//其他所有路徑都需要許可權校驗
.and()
.csrf().disable()//預設開啟,可以顯示關閉
.formLogin() //內部註冊 UsernamePasswordAuthenticationFilter
.loginPage("/login.html") //表單登入頁面地址
.loginProcessingUrl("/login")//form表單POST請求url提交地址,預設為/login
.passwordParameter("password")//form表單使用者名稱引數名
.usernameParameter("username") //form表單密碼引數名
.successForwardUrl("/success.html") //登入成功跳轉地址
.failureForwardUrl("/error.html") //登入失敗跳轉地址
//.defaultSuccessUrl()//如果使用者沒有訪問受保護的頁面,預設跳轉到頁面
//.failureUrl()
//.failureHandler(AuthenticationFailureHandler)
//.successHandler(AuthenticationSuccessHandler)
//.failureUrl("/login?error")
.permitAll();//允許所有使用者都有許可權訪問loginPage,loginProcessingUrl,failureForwardUrl
第三個方法: com.hou.security.config.WebSecurityConfig.configure(WebSecurity web) throws Exception 這個方法是配置security框架中那些filter的資訊,以及忽略哪些路徑等,直接配置所有filter web.ignoring().antMatchers("/js/", "/css/", "/images/**");
demo我已經放在github上,大家可以檢視https://github.com/guojizhongnan/security.git
demo原始碼中註釋非常詳細,大家可以結合原始碼看步驟