Spring Security修煉手冊(四)————Security默認表達式的權限控制

        前三章主要講的是Security對於認證的處理,那麼本節,會爲你們介紹基於Security默認表達式的權限控制(較爲簡單,沒法知足複雜權限控制及多變的權限規則,後面會介紹基於自定義表達式的權限訪問控制,可知足99%的業務場景的需求)。java

1、介紹及使用

 直接進入主題,基於默認的表達式權限控制,須要在SecurityConfig中配置,代碼以下:app

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
	
	@Autowired
	private SecurityProperties securityProperties;
	@Autowired
	private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
	@Autowired
	private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
	@Bean
	public PasswordEncoder passwordEncoder(){
		
		return new BCryptPasswordEncoder();
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
		http
			.formLogin()
				.loginPage(securityProperties.getToLoginProperties().getLoginProperties().getLoginPage())//用戶未認證時,轉跳到認證的頁面
				.loginProcessingUrl(securityProperties.getToLoginProperties().getLoginProperties().getLoginProcessingUrl())//form中action的地址,也就是處理認證請求的URL	
				.usernameParameter(securityProperties.getToLoginProperties().getLoginProperties().getUsernameParameter())//form中用戶名密碼的name名
				.passwordParameter(securityProperties.getToLoginProperties().getLoginProperties().getPasswordParameter())
				.defaultSuccessUrl(securityProperties.getToLoginProperties().getLoginProperties().getDefaultSuccessUrl())//認證成功後默認轉跳的URL
				.successHandler(myAuthenticationSuccessHandler)
				.failureHandler(myAuthenticationFailureHandler)
		.and()
		.authorizeRequests()
			.antMatchers(securityProperties.getToLoginProperties().getLoginProperties().getLoginPage(),
					     securityProperties.getToLoginProperties().getLoginProperties().getLoginProcessingUrl()).permitAll()
			.antMatchers(HttpMethod.GET,"/vip").hasRole("admin")//默認權限表達式
			.anyRequest().authenticated()
		.and()
			.csrf().disable()
			;
	}
	
	

}

    上面代碼的含義是,「/vip」這個URL必須是GET請求,且擁有admin權限的用戶才能夠訪問。接下來咱們配置一下UserDetailServer,模擬給用戶一個admin權限。框架

@Component
public class MyUserDetailsServer implements UserDetailsService {

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		if("admin".equals(username)){
			
			throw new RuntimeException("admin禁止登陸");
		}
		return new User(username, "$2a$10$ofPkBDUezOJp6Sik63Q/0.QlU8a1itEyzldjSXqfn2nDPqXjN0Ljm", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
	}

}

    AuthorityUtils是Security提供的一個工具類,我使用的這個方法的功能是將一個以「,」分割的字符串轉換成UserDetail中第三個參數所須要的Collection<? extends GrantedAuthority>。ide

    所有配置好後咱們重啓項目,登陸。能夠看到,我是擁有admin這個權限的,按道理說我有權限訪問「/vip」,咱們訪問一下試試。工具

  

    奇怪?我明明擁有「admin」權限,爲何訪問「/vip」確是403,請求被拒絕呢?spa

2、默認權限表達式源碼解析

    第一節中,咱們明明能夠在Authorites看到當前用戶擁有了admin權限,可是卻訪問被拒絕!這又是爲何呢?下面,我帶着你們走一邊Security的源碼,看一看究竟是哪裏出現了問題。code

    咱們依舊在UserdetailsServer中打上斷點。orm

    重啓項目,登錄後,訪問「/vip」查看斷點堆棧信息。咱們只看最後一個過濾器,這裏咱們說過,他會讀取咱們的SecurityConfig的配置信息,作匹配。咱們能夠看到雖然咱們配置的「/vip」須要的權限是admin,可是框架卻自動爲咱們加上了「ROLE_」的前綴,因此,這就是咱們爲何匹配不到,無權限訪問的緣由。csrf

    咱們稍做修改,將UserDetailsServer中的權限加上這個前綴。ip

咱們重啓項目,再次訪問,能夠看到已經有權限了,404是因爲我沒有寫這個頁面。

3、自定義異常頁面

    在前面的介紹中,不管是403仍是404,咱們使用的都是提供的默認頁面實現,而在咱們的實際業務中須要咱們使用本身的異常頁面,那麼怎麼配置呢?方法有不少種,好比404頁面,咱們能夠寫一個不徹底匹配的@RequestMapping 這樣因爲不徹底匹配的優先級是小於徹底匹配的優先級的,因此當匹配不到映射的時候就會匹配咱們的404了。

    可是我既然單獨拿出來寫一章,其實徹底爲了湊字數(一不當心說了實話),那確定就是有更好的方法的,其實在Spring Boot中,只須要在默認靜態資源目錄下建立一個與狀態碼同名的頁面,就會在出現異常的時候進入到你的頁面中。至於Spring boot的默認資源目錄是什麼,怎麼改,請看個人Spring boot系列博客。

咱們訪問試一下:

相關文章
相關標籤/搜索