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/