【问题标题】:Spring Boot, Spring Security - Prevent direct URL query of MongoDBSpring Boot、Spring Security - 防止 MongoDB 的直接 URL 查询
【发布时间】:2018-04-26 21:35:56
【问题描述】:

所以,我正在开发一个使用 Spring Security 进行登录身份验证的 Spring Boot Web 应用程序。目前,我们有三种类型的用户被重定向到相应的仪表板,当他们尝试通过直接 URL 访问其他仪表板时,他们被拒绝访问。任何未经身份验证的用户也被拒绝访问该站点的其余部分。在测试时,我发现一旦用户成功通过身份验证,如果他们要使用指向“/”或 localhost:8080 的直接 URL 进行测试,而不是像未通过身份验证时那样被重定向到登录页面,将返回包含 MongoDB 实例中表信息的 JSON。更糟糕的是,如果他们将表名附加到 URL,他们将收到 JSON 格式的整个表。

示例:http://localhost:8080/premios(当前持有虚拟值)

{
  "_embedded" : {
    "premios" : [ {
      "title" : "hdlkfjgd",
      "description" : "dflgkj",
      "points" : 20,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        }
      }
    }, {
      "title" : "dfdggd",
      "description" : "dfgd",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        }
      }
    }, {
      "title" : "alksksjlkakjf",
      "description" : "sdlkfkjsdlfkj",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/premios{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/premios"
    },
    "search" : {
      "href" : "http://localhost:8080/premios/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 3,
    "totalPages" : 1,
    "number" : 0
  }
}

如何防止这种情况发生?这是因为我如何设置 Spring Security,还是我需要在我们的 mLab 上做一些事情以只允许后端的控制器进行查询?上面的 premios URL 不是我们任何控制器中定义的请求方法,所以我不确定它为什么起作用。以下是它的配置方式:

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SimpleAuthenticationSuccessHandler successHandler;

    @Autowired
    public void configureGlobal(
            AuthenticationManagerBuilder auth,
            CustomUserDetailsService userDetailsService) throws Exception {
        auth
          .userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http)
            throws Exception {
        http
          .csrf().disable()
          .authorizeRequests()
            .antMatchers("/css/**", "/js/**", "/images/**", "/script/**").permitAll()
            .antMatchers("/signup").permitAll()
            .antMatchers("/webapp/admin").hasRole("ADMIN")
            .antMatchers("/webapp/sales").hasRole("SALES")
            .antMatchers("/webapp/business").hasRole("USER")
            .anyRequest().authenticated()
            .and()
          .formLogin()
            .successHandler(successHandler)
            .loginPage("/login")
            .permitAll()
            .and()
          .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher(("/logout")))
            .logoutSuccessUrl("/login")
            .permitAll();
    }
}

SimpleAuthenticationSuccessHandler.java

@Component
public class SimpleAuthenticationSuccessHandler implements AuthenticationSuccessHandler{

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication) throws IOException, ServletException {

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        authorities.forEach(authority -> {
            if(authority.getAuthority().equals("ROLE_ADMIN")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/admin");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_SALES")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/sales");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_USER")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/business");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else {
                throw new IllegalStateException();
            }
        });
    }
}

也许,这与成功处理程序有关?我是使用 Spring Boot 和构建 Web 应用程序的新手,因此非常感谢任何帮助!

【问题讨论】:

    标签: mongodb spring-boot spring-security


    【解决方案1】:

    对于有类似问题的任何人,我通过更改解决了我的问题:

    .anyRequest().authenticated() 
    

    .anyRequest().denyAll(). 
    

    一旦用户通过身份验证,他们就可以向我们的 Web 应用发出任何请求。通过使用denyAll,我们可以阻止所有未在我们的antmatchers 中指定的请求。我还修改了这样的antmatchers:

    .antMatchers("/webapp/business").hasRole("USER")
    

    .antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
    

    为了以防万一,我确保将任何对“/”的请求重新路由到我们的登录页面“/login”。

    【讨论】:

      猜你喜欢
      • 2015-10-19
      • 1970-01-01
      • 2019-10-05
      • 2017-09-26
      • 2019-07-07
      • 2017-09-11
      • 2023-03-29
      • 1970-01-01
      • 2021-11-21
      相关资源
      最近更新 更多