Maven依賴
1 <dependencies> 2 <!-- ... other dependency elements ... --> 3 <dependency> 4 <groupId>org.springframework.security</groupId> 5 <artifactId>spring-security-web</artifactId> 6 <version>4.2.3.RELEASE</version> 7 </dependency> 8 <dependency> 9 <groupId>org.springframework.security</groupId> 10 <artifactId>spring-security-config</artifactId> 11 <version>4.2.3.RELEASE</version> 12 </dependency> 13 </dependencies>
要點
configureGlobal(AuthenticationManagerBuilder auth)方法:用來配置獲取和核對用戶信息
configure(HttpSecurity http)方法:用來配置訪問資源對應的權限
開啟Spring Security:在配置類頭上加注解@EnableWebSecurity
1 @Configuration 2 @EnableWebSecurity 3 public class SecurityConfig { 4 5 @Autowired 6 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 7 auth 8 .inMemoryAuthentication() 9 .withUser("user").password("password").roles("USER"); 10 } 11 }
這個類的配置將產生如下作用:
-
要求驗證所有請求應用的URL
-
產生一個登錄表單界面
-
只允許使用類中指定的“user”和“password”進行登錄才驗證通過
-
運行用戶登出(使用post方便訪問“/logout”URL)
-
第8行定義一個在內存中(in memory)的用戶,用戶名為“user”,密碼為“password”,角色為“USER”
初始化:定義一個繼承於AbstractSecurityWebApplicationInitializer的類
- 如果不使用Spring 或者Spring MVC,則你需要在這個類中加載上面的配置類,如下
1 public class SecurityWebApplicationInitializer 2 extends AbstractSecurityWebApplicationInitializer { 3 4 public SecurityWebApplicationInitializer() { 5 super(SecurityConfig.class); 6 } 7 }
- 如果使用Spring 或者Spring MVC,只需將這個類置空即可,然后在Spring MVC的啟動類中加載SpringSecurity配置類,以下示例的Spring MVC也是基於Java注解配置的,可以看我的另一篇博客Spring完全基於Java和注解配置,如下
1 public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { 2 }
1 public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 2 @Override 3 protected Class<?>[] getRootConfigClasses() { 4 return new Class[] { WebSecurityConfig.class }; 5 } 6 // ... other overrides ... 7 }
第一種方法的SecurityWebApplicationInitializer
將會:
-
自動注冊springSecurityFilterChain Filter攔截所有的URL
-
添加一個ContextLoaderListener去加載 上面定義SecurityConfig配置類
springSecurityFilterChain Filter:負責應用的所有安全,包括保護URL的訪問、驗證提交的用戶名和密碼、重定向到登錄表單等
自定義登錄界面
修改SecurityConfig類,WebSecurityConfigurerAdapter類提供一些方便的默認設置,使應用程序快速運行。
1 @EnableWebSecurity 2 public class SecurityConfig extends WebSecurityConfigurerAdapter { 3 4 @Override 5 protected void configure(HttpSecurity http) throws Exception { 6 http 7 .authorizeRequests() 8 .antMatchers("/resources/**").permitAll() 9 .anyRequest().authenticated() 10 .and() 11 .formLogin() 12 .loginPage("/login") 13 .permitAll() 14 .and() 15 .logout() 16 .permitAll(); 17 } 18 19 // ... 20 }
該配置提供:
- 驗證每個請求,除了以“/resources/”開頭的URL
- 支持基於表單驗證,登錄頁面為“/login”對應的文件
- 支持基於http驗證
其中loginPage("/login")
指示:
-
請求驗證時被重定向到 /login
-
驗證失敗失敗時被重定向到 /login?error
-
登出成功時會被重定向到 /login?logout
permitAll()方法聲明允許在未驗證時任何訪問到的資源和URL,如果不加則連訪問
/login 都會一直被重定向
HttpSecurity類:類似XML配置中的<http>元素,可以配置基於web的安全請求,默認下,它會作用於所有的請求,但是可以使用 requestMatcher(RequestMatcher)等類似方法進行限制
以下方法定義只有“USER”角色的用戶才能訪問“/”URL(即任何請求)
1 protected void configure(HttpSecurity http) throws Exception { 2 http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin(); 3 }
常用方法:
antMatcher(String antPattern):配置只有當匹配該路徑模式時才調用
HttpSecurity
authorizeRequests():限制基於HttpServletRequest之上的使用
csrf():添加CSRF支持
configureGlobalSecurity(AuthenticationManagerBuilder auth)用來指定從何處獲取用戶
configure(HttpSecurity http)用來配置訪問每個URL所需的對應權限
UserDetails
UserDetails 是一個 Spring Security 的核心接口,代表一個主體(包含於用戶相關的信息)。
在 Authentication 接口中有一個方法 Object getPrincipal(); 這個方法返回的是一個安全主題,大多數情況下,這個對象可以強制轉換成 UserDetails 對象,獲取到UerDetails 對象之后,就可以通過這個對象的 getUserName()方法獲取當前用戶名。
自定義驗證:通過暴露類型為AuthenticationProvider或者UserDetailsService的bean,使用的驗證設置優先級高到低排序為AuthenticationManagerBuilder、AuthenticationProvider、UserDetailsService,即要是發現存在使用前者的配置,則后者的配置無效
通過暴露一個PasswordEncoder類型的bean來定義密碼使使用何種編碼,如下使用bcrypt
@Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
開啟方法注解
在任何配置類(使用@Configuration注解的類)頭上添加 @EnableGlobalMethodSecurity注解,然后就可以使用@Secured等方法級注解進行安全配置,可以為方法定義一系列屬性,這些配置將會通過AccessDecisionManager來實際決定