Spring Boot、Spring Security - 防止 MongoDB 的直接 URL 查询
Posted
技术标签:
【中文标题】Spring Boot、Spring Security - 防止 MongoDB 的直接 URL 查询【英文标题】:Spring Boot, Spring Security - Prevent direct URL query of MongoDB 【发布时间】: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 应用程序的新手,因此非常感谢任何帮助!
【问题讨论】:
【参考方案1】:对于有类似问题的任何人,我通过更改解决了我的问题:
.anyRequest().authenticated()
到
.anyRequest().denyAll().
一旦用户通过身份验证,他们就可以向我们的 Web 应用发出任何请求。通过使用denyAll,我们可以阻止所有未在我们的antmatchers 中指定的请求。我还修改了这样的antmatchers:
.antMatchers("/webapp/business").hasRole("USER")
到
.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
为了以防万一,我确保将任何对“/”的请求重新路由到我们的登录页面“/login”。
【讨论】:
以上是关于Spring Boot、Spring Security - 防止 MongoDB 的直接 URL 查询的主要内容,如果未能解决你的问题,请参考以下文章
Grails Spring Core 安全插件 - 无法解析类