用于未经授权的ldap组访问的Spring Boot Whitelabel页面错误

时间:2019-02-22 23:55:18

标签: spring-boot spring-security ldap

我正在Spring Boot 2.0.0和Spring Security 5.0.6中开发一个Web应用程序,并且在添加验证用户是否属于LDAP组的逻辑之前,我一直运气很好。如果用户提供了无效的凭据,则会再次显示登录页面,并显示验证错误,但是当凭据正确但用户不属于必需的LDAP组时,会将应用程序重定向到Whitelabel Error页面,粗体字母标题显示如下:

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Feb 22 18:40:55 EST 2019
There was an unexpected error (type=Forbidden, status=403).
Forbidden

这是正确的错误,因此我知道身份验证有效。但是我想保留在登录页面上而不重定向,因此我不知道该怎么做。

我的WebSecurityConfigurerAdapter的整个配置方法如下所示:

   @Override
   protected void configure(HttpSecurity http) throws Exception {
      // Disabling CSRF because it causes issues with API requests (POSTs don't
      // contain the CSRF tokens).
      http.csrf().disable();

      http.headers().frameOptions().disable();

      http.authorizeRequests()

            // This line turns off authentication for all management endpoints, which means all
            // endpoints that start with "/actuator" (the default starter path for management endpoints
            // in spring boot applications).  To selectively choose which endpoints to exclude from authentication,
            // use the EndpointRequest.to(String ... method, as in the following example:
            // .requestMatchers(EndpointRequest.to("beans", "info", "health", "jolokia")).permitAll()
            .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()

            // Do not authenticate resource requests
            .antMatchers(
                  "/app/css/**",
                  "/app/img/**",
                  "/app/js/**",
                  "/app/bootstrap/**").permitAll()

            .antMatchers(
                  "/admin/**",
                  "/app/builds/**",
                  "/app/monitor/**",
                  "/app/review/**")
               .hasRole(requiredRole)

            // All other requests are authenticated
            .anyRequest().authenticated()

            // Any unauthenticated request is forwarded to the login page
            .and()
            .formLogin()
            .loginPage(LOGIN_FORM)
            .permitAll()
            .successHandler(successHandler())

            .and()
            .exceptionHandling()
            .authenticationEntryPoint(delegatingAuthenticationEntryPoint())

            .and()
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_FORM))
            .logoutSuccessUrl(LOGIN_FORM);
   }

我很乐意批评整个方法的构造,顺便说一句-我已经接手了这个项目,这对我来说是新的。在我引入以.hasRole(requiredRole)结尾的6行之前,这段代码运行良好,只要用户属于必需组的一部分,它仍然可以正常工作。

我还没有提供此处调用的某些方法的源代码,如果有人愿意,我很乐意将其粘贴。我猜想一个很了解这些知识的人会立即发现问题。

任何建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

我找到的解决方案类似于通过谷歌搜索发现的解决方案。我创建了一个解析为/ error的错误控制器。起初,我认为我的错误处理程序从未到达过,因为我没有在编辑器中正确配置它来调试Spring Boot应用程序,但今天早上我解决了。我添加了一个看起来像这样的错误控制器:

@Controller
public class MyErrorController implements ErrorController {
   private static final String ERROR_PATH = "/error";

   @Autowired
   private ErrorAttributes errorAttributes;

   @RequestMapping(value = ERROR_PATH)
   public String error(WebRequest request, HttpServletRequest httpServletRequest) {
      Map<String, Object> attrs = this.errorAttributes.getErrorAttributes(request, false);

      Integer status = (Integer) attrs.get("status");
      if (status != null && status == 403) {
         httpServletRequest.setAttribute("unauthorized", true);
      }

      return "/app/login";
   }

   @Override
   public String getErrorPath() {
      return ERROR_PATH;
   }
}

因此,每当进行未经授权的尝试时,都会击中该控制器,并且状态403的条件会触发此方法中的逻辑分支。我添加了请求属性“未经授权”,并转到登录jsp页面,在该页面上添加了一个部分,用于检测请求属性的存在。瞧,我已经准备好了。