一、HttpSecurity源碼
HttpSecurity類是Spring Security核心配置類之一,用來配置Spring Security的行為,包括認(rèn)證方式、權(quán)限控制、CSRF保護(hù)等。我們先來看一下HttpSecurity類的源碼結(jié)構(gòu):
@Configuration
public final class HttpSecurity extends
AbstractConfiguredSecurityBuilder
implements SecurityBuilder, SecurityConfigurerAware, HttpSecurity>, HttpSecurityBuilder {
// 構(gòu)造方法
public HttpSecurity(ObjectPostProcessor objectPostProcessor, AuthenticationManagerBuilder builder,
Map, Object> sharedObjects) {
super(objectPostProcessor, true, sharedObjects);
// come code here...
}
// 配置方法
public HttpSecurity requestMatcher(RequestMatcher requestMatcher) {
// some code here...
return this;
}
// some other methods...
}
如上代碼所示,HttpSecurity是一個(gè)@Configuration配置類,繼承了AbstractConfiguredSecurityBuilder類,并實(shí)現(xiàn)了SecurityBuilder和SecurityConfigurerAware接口。其中,requestMatcher方法用于匹配請(qǐng)求的URL,根據(jù)匹配結(jié)果來對(duì)請(qǐng)求進(jìn)行處理。
二、HttpSecurity的用法
使用方法可以分為以下幾步:
1、創(chuàng)建一個(gè)SecurityConfigurer,并在其中重寫configure方法,實(shí)現(xiàn)對(duì)HttpSecurity的配置;
2、通過調(diào)用HttpSecurity的apply方法,并傳入第一步創(chuàng)建的SecurityConfigurer,來將SecurityConfigurer中的配置應(yīng)用到HttpSecurity中;
3、配置成功后,HttpSecurity會(huì)返回一個(gè)DefaultSecurityFilterChain類型的對(duì)象,用于構(gòu)建安全過濾器鏈。
三、HttpSecurity配置
3.1 HttpSecurity默認(rèn)配置
當(dāng)我們沒有對(duì)HttpSecurity進(jìn)行額外的配置時(shí),Spring Security會(huì)使用默認(rèn)配置。默認(rèn)配置包括以下內(nèi)容:
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
以上代碼表示,所有請(qǐng)求需要進(jìn)行身份驗(yàn)證,并且要求用戶使用表單登錄或HTTP基本認(rèn)證。
3.2 HttpSecurity權(quán)限配置詳解
針對(duì)不同路徑和請(qǐng)求類型,我們可以配置不同的授權(quán)策略。
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
以上代碼表示,對(duì)于"/admin/**"路徑下的請(qǐng)求,需要有"ADMIN"角色方可訪問;對(duì)于"/db/**"路徑下的請(qǐng)求,需要有"ADMIN"和"DBA"兩個(gè)角色方可訪問;而其他請(qǐng)求只需要在通過身份驗(yàn)證后即可訪問。同時(shí),我們還可以設(shè)置登錄頁和退出頁。
3.3 HttpSecurity解密失敗怎么回事
解密失敗可能是因?yàn)榭蛻舳藗鬟f的數(shù)據(jù)被篡改或者密鑰不正確,當(dāng)出現(xiàn)解密失敗的情況,可以使用以下代碼對(duì)HttpSecurity進(jìn)行配置:
http.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.accessDeniedHandler(new AccessDeniedHandlerImpl());
以上代碼為設(shè)置Http403ForbiddenEntryPoint和AccessDeniedHandlerImpl類,用于處理解密失敗后的異常情況。
四、完整代碼示例
下面是一個(gè)完整的HttpSecurity配置示例:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.accessDeniedHandler(new AccessDeniedHandlerImpl());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
以上代碼為一個(gè)完整的Spring Security配置類示例,其中包含了對(duì)HttpSecurity和AuthenticationManagerBuilder的配置。