2010-11-15 41 views
10

我在Spring Security 3.0.x(特別是3.0.2)中遇到了一個小問題。除非沒有權限的人嘗試登錄,否則我正在處理的所有應用程序都能正常工作。如何使用Spring Security 3.0.x處理HTTP 403

當它發生時,用戶會被重定向到「歡迎」頁面上,因爲他的用戶名/密碼是正確的,他收到一個可愛的白色頁面,這樣的:「錯誤403:訪問被拒絕」

所以,我一直在尋找網絡,試圖找出如何處理這種行爲。到目前爲止,我已經得出結論,如果我錯了,請糾正我,它由ExceptionTranslationFilter管理。但我不太明白如何充分利用這些信息。

我tryied編輯我SecurityContext.xml到禁止訪問的處理器標記添加到我的HTTP標籤,但它不工作。我是否需要添加超過此標籤才能使其工作?是否有其他可能性使我的應用程序更加用戶友好?

編輯:我想重定向到一個頁面,讓我們說403.html,例如。

誠懇,
感謝

+0

什麼是理想的行爲? – axtavt 2010-11-15 16:57:03

+0

添加了所需的行爲 – ALOToverflow 2010-11-15 18:29:53

+1

您如何使用標籤?你使用類似這樣的東西嗎?:並且在你的控制器中你有一個controllerUrl,它返回到403.html – Javi 2010-12-02 16:50:37

回答

7

我發現如何做到這一點。通過實現AccessDeniedHandler接口和相應的句柄方法,我可以輕鬆地控制Http 403錯誤的處理方式。

這樣,您可以在會話中添加各種項目,然後在jsp上攔截它們。

的xml文件則是這樣的:

<sec:http> 
    <!-- lots of urls here --> 
    <sec:access-denied-handler ref="accessDeniedHandler" /> 
    <sec:anonymous/> 
</sec:http> 

<bean id="accessDeniedHandler" class="foo.bar.CustomAccessDeniedHandler"> 
    <property name="accessDeniedUrl" value="403.html" /> 
</bean> 

的Java類:

package foo.bar; 
public class CustomAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler { 
private String accessDeniedUrl; 

    public CustomAccessDeniedHandler() { 
    } 

    public CustomAccessDeniedHandler(String accessDeniedUrl) { 
     this.accessDeniedUrl = accessDeniedUrl; 
    } 

    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { 
     response.sendRedirect(accessDeniedUrl); 
     request.getSession().setAttribute("CustomSessionAttribute", "value here"); 
    } 

    public String getAccessDeniedUrl() { 
     return accessDeniedUrl; 
    } 

    public void setAccessDeniedUrl(String accessDeniedUrl) { 
     this.accessDeniedUrl = accessDeniedUrl; 
    } 
} 

而且一個jsp例如:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<c:if test="${!empty CustomSessionAttribute}"> 
    <br/> 
    ACCESS IS DENIED 
    <br/> 
</c:if> 
<!-- other stuff down here --> 
+0

你不需要實現自定義處理程序 – MounirReg 2012-08-12 15:24:38

+0

爲什麼downvote?我並不是說這是做這件事的唯一方式,但我說這是一種行之有效的方式。另外請記住,這與Spring Security 3.0.2有關,並且這個問題已經有2年的歷史了。事情現在可能已經改變了。 – ALOToverflow 2012-08-12 16:29:43

+0

當我找到這個頁面(正在尋找403攔截)時,你的答案和其他答案的評分相同,但是你的答案被標記爲正確答案。正如你所說,問題是2歲,但尋找解決方案的人會更喜歡其他答案。這並不意味着你的不好。 – MounirReg 2012-08-14 12:21:29

3

,使這項工作的方式是在你的入口點來定義一個處理程序:

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { 
    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException { 

     if (authException != null) { 
      // you can check for the spefic exception here and redirect like this 
      response.sendRedirect("403.html"); 
     } 
    } 
} 

你可以通過設置這個作爲你進入它定義爲您的入口點在XML配置文件中的一點:

<http entry-point-ref="customAuthenticationEntryPoint"> 

    ... 

</http> 
9

一個更清潔的方式來處理錯誤重定向是使用<error-page><error-code>標籤在您的web.xml中。請參閱下面的示例:

<!-- Custom 403 Error Page --> 
<!-- 
      NOTE: Security will throw this error when a user has been authenticated successfully 
      but lacks the permissions to perform the requested action. 
    --> 
    <error-page> 
     <error-code>403</error-code> 
     <location>/403.jsp</location> 
    </error-page> 

只要遇到指定的錯誤代碼,該代碼塊就會重定向到指定的位置。

這消除了您的應用程序邏輯內部需要授權代碼。

+1

雖然您無法訪問「身份驗證」對象,所以任何'http:// www正在使用的.springframework.org/security/tags'標記將無法訪問,導致這些標記中的所有內容都不會顯示。 – 2013-10-08 14:55:37

+1

這是完全正確的,並且指出未來的讀者很好。最好的策略完全取決於人們希望他們的應用程序如何處理認證錯誤。如果您想在某人未通過身份驗證時進行某種信息處理,那麼由於您陳述的觀點,此解決方案無法正常工作。如果您只是想將用戶發送到Cookie模式的拒絕訪問頁面,那麼我喜歡使用此解決方案,因爲它不會與我的其他應用程序代碼混在一起。 – 2013-10-09 16:05:21

+0

@KristenD。您能否說明應該如何設置錯誤頁面facelet的**位置**?我的頁面沒有重定向。這是'webapp'文件夾中的相對路徑嗎?在你的情況下,錯誤頁面直接放在該文件夾中?非常感謝你! – BBerry 2016-05-26 07:43:03

1

您已經檢查了應用程序中的標記,並且對我來說它似乎工作正常。

<sec:access-denied-handler error-page="/handle403Url" /> 

其中handle403Url我想調用來處理此錯誤(例如顯示錯誤)。

不要忘記,你必須讓這個網址的過濾器,因此它可以通過該用戶權限來達到,所以在flters開始你要添加的東西是這樣的:

<sec:intercept-url pattern="/handle403Url" filters="none" /> 
21

我還是不明白你爲什麼必須實現您自己的訪問處理程序...我目前面臨着相同的任務:

<security:access-denied-handler error-page="/accessDenied"/> - works like charm. 

不要忘了在你的控制器到指定的處理程序:

@RequestMapping(value = "/accessDenied") 
     public String accessDenied() { 

      return "accessDenied"; // logical view name 
     } 

更新春季啓動(2014年10月):

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.exceptionHandling().accessDeniedHandler(customHandler) OR .accessDeniedPage("/somePage.html").and 
      .formLogin() 
       .failureHandler(ajaxAuthenticationFailureHandler)} 

現在我們真的不返回意見對於這樣的任務,因爲角js的踢,所以你可以使用你的失敗/成功處理程序並返回定製的JSON響應。對於我們來說,使用失敗處理程序就足夠了,但是你可以選擇你想要控制的地方。我們通常不使用視圖解析器,因爲UI瓦片框架(例如角度偏差)能夠構建成單個頁面爲你。 HTML片段存儲在服務器上,並僅作爲靜態資源提供。

可以使用嵌入式Tomcat來實現與web.xml類似的行爲!

@Configuration 
@EnableAutoConfiguration 
public class ApplicationWebXml extends SpringBootServletInitializer { 

private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); 

@Override 
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
    return application.profiles(addDefaultProfile()) 
      .showBanner(false) 
      .sources(Application.class); 
} 

//required for container customizer to work, the numerous tutorials didn't work for me, so I simply tried overriding the default one 
@Bean 
public EmbeddedServletContainerFactory servletContainer() { 
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); 
    return tomcat; 
} 

@Bean 
public EmbeddedServletContainerCustomizer containerCustomizer(

) { 
    return new EmbeddedServletContainerCustomizer() { 
     @Override 
     public void customize(ConfigurableEmbeddedServletContainer container) { 
      TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container; 
      containerFactory.setSessionTimeout(1); // just for your interest, remove as necessary 

      containerFactory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/views/accessDenied.html"), 
        new ErrorPage(HttpStatus.NOT_FOUND,"/views/notFound.html")); 
      containerFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() { 
       @Override 
       public void customize(Connector connector) { 
        connector.setPort(8082);// just for your interest, remove as necessary 
       } 
      }); 
     } 
    }; 
} 

}

+0

我最喜歡你的回答。 – denu 2012-08-06 19:57:47

+0

這是最好的解決方案,因爲定義'web.xml'中的錯誤頁面將不會提供用戶訪問JSP視圖中的彈簧安全標記,就像模板頁面導致看似缺少的內容(即菜單,用戶名等...)。 – 2013-10-08 14:54:34

相關問題