代码之家  ›  专栏  ›  技术社区  ›  ALOToverflow

如何使用SpringSecurity3.0.x处理HTTP 403

  •  12
  • ALOToverflow  · 技术社区  · 14 年前

    我面临着一个关于SpringSecurity3.0.x(目前特别是3.0.2)的小问题。我正在处理的整个应用程序都工作得很好,除非有没有权限的人试图登录。

    当它发生时,用户被重定向到“欢迎”页面,因为他的用户名/密码是有效的,并且他收到一个可爱的白色页面:“错误403:访问被拒绝”

    所以,我一直在网上寻找如何处理这种行为。到目前为止,我已经得出结论,如果我错了,请纠正我,它是由 ExceptionTranslationFilter . 但我不太明白如何充分利用这些信息。

    我试图编辑SecurityContext.xml以添加 拒绝访问处理程序 标记到我的 http 标签,但不起作用。我需要添加更多的标签才能工作吗?有没有其他方法可以让我的应用程序更方便用户?

    编辑 :我想重定向到一个页面,例如403.html。

    罪恶的,
    谢谢

    5 回复  |  直到 14 年前
        1
  •  22
  •   Aubergine    10 年前

    我还是不明白你为什么要实现自己的访问处理程序。。。我目前面临着同样的任务:

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

    不要忘记在控制器中指定处理程序:

     @RequestMapping(value = "/accessDenied")
          public String accessDenied() {
    
                return "accessDenied"; // logical view name
           }
    

    Spring Boot(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)} 
    

    现在,由于angular js的出现,我们并没有真正返回此类任务的视图,因此您可以使用失败/成功处理程序并返回定制的JSON响应。对于我们来说,使用故障处理程序就足够了,但是您可以选择希望控件启动的位置。我们通常不使用视图解析器,因为有一些UI tiles框架(如角度部分)能够为您将片段构造成单个页面。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
                    }
                });
            }
        };
    }
    

    }

        2
  •  9
  •   Kristen D.    14 年前

    处理错误重定向的更干净的方法是使用 <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>
    

    每当遇到指定的错误代码时,此代码块将重定向到指定的位置。

    这样就不需要在应用程序逻辑中使用授权代码。

        3
  •  8
  •   ALOToverflow    14 年前

    我已经找到怎么做了。通过实施 AccessDeniedHandler 接口和相应的handle方法我可以很容易地控制htp403错误的处理方式。

    这样,您可以在会话中添加各种项,然后在您的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 -->
    
        4
  •  3
  •   Grant Cermak    14 年前

    执行此操作的方法是在入口点中定义处理程序:

    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>
    
        5
  •  1
  •   Javi    14 年前

    你已经在一个应用程序中检查了标签,对我来说它似乎工作了。

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

    我要调用handle403Url来处理此错误(例如显示错误)。

    别忘了,您必须在筛选器中允许此url,以便此用户权限可以访问它,所以在flters的开头,您必须添加如下内容:

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