1. 程式人生 > >淺談spring security 403機制

淺談spring security 403機制

403就是access denied ,就是請求拒絕,因為許可權不足

三種許可權級別

一、無許可權訪問

<security:http security="none" pattern="/index.jsp"   />

這種即是不需要登入,也可以訪問的,但是不會傳csrf_key

二、匿名訪問

<security:http>

<security:intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

</security:http>

這種也是不需要登入就訪問的,但是會傳csrf_key

三、有許可權訪問

<security:http>

<security:intercept-url pattern="/index.jsp" access="xxxxx"/>

</security:http>

這種就需要使用者登入了,而且需要相應的許可權才能訪問,不然就報403(access denied)

沒有跳轉403?

今天遇到了一個詭異的問題

admin.jsp設定為access="USER",需要使用者登入了,而且需要有USER許可權才能訪問

然而我沒登陸的時候,去訪問admin.jsp,結果沒有跳到403頁面,跳到了login.jsp

在我預想的是,跳到403

原因

當用戶已經登入了,但是許可權不足,才會跳轉到403

當用戶沒有登入的時候,訪問有許可權的頁面,只會跳轉到登陸頁面

機制

spring security處理請求的時候,先會檢測使用者是否登入,也就是檢測是否有authentication(身份)

此時,如果使用者沒有登入,而且請求是需要登入的action,spring security會跳轉到登陸頁面,就算這個頁面需要許可權訪問,也不會出現403。

登入的時候,會在SecurityContextHolder裡面放一個記錄使用者資訊(使用者名稱、許可權)的principal,需要驗證使用者許可權的時候,就會從SecurityContextHolder取出principal來驗證許可權。

如果使用者已經登入了(有了authentication),如果使用者的許可權不足,就會報403 這個時候security:access-denied-handler才會生效

自定義403

想要自定義403,需要在spring-security.xml裡面設定security:access-denied-handler

有兩種方式:

指定AccessDeniedHandler

自定義一個403處理機制,需要實現AccessDeniedHandler介面,實現裡面的handle方法

當權限不足的時候,spring security會呼叫handle方法

可以在handle方法裡面重定向或者轉發請求

程式碼demo

public class AccessDeniedServletHandler implements AccessDeniedHandler {

	private static final String DEF_ERROR_PAGE_PATH="action/deniedServlet_denied";
	
	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response,
			AccessDeniedException accessDeniedException) throws IOException, ServletException {
		response.sendRedirect(DEF_ERROR_PAGE_PATH);
	}

}

在spring-security.xml配置

<security:access-denied-handler ref="accessDeniedServletHandler" />

<bean id="accessDeniedServletHandler" class="com.xxx.servlet.AccessDeniedServletHandler" scope="singleton"></bean>

指定error-page

這種方式,實際上是轉發請求,做不到重定向

在spring-security.xml配置

<security:access-denied-handler error-page="403.html" />

整合Struts的問題

情景

前提:自定義的403頁面的URL,是通過struts的action訪問的

當權限不足的時候,將請求轉發到自定義的403頁面時,會出現404( not found)

但是直接訪問403頁面的時候,又是正常的

原因

所以推測

spring security 的DefaultSecurityFilterChain在strust的filter之後

所以struts捕獲不到請求的403頁面,但是請求方式又是action,所以就找不到頁面了

結論

所以這樣子的話,一切spring security 處理完成後自定義跳轉,都是在strust的filter之後的

像登入成功的authentication-success-handler-ref,退出的success-handler-ref以及access denied的security:access-denied-handler

所以訪問action的小心的,要用重定向的方式



檢視原文:http://139.129.55.235/2016/06/01/%e6%b5%85%e8%b0%88spring-security-403%e6%9c%ba%e5%88%b6/