因此,我正在开发一个Spring Boot Web App,它利用Spring Security进行登录验证。目前,我们有三种类型的用户被重定向到相应的仪表板,当他们尝试通过直接URL访问其他仪表板时,他们被拒绝访问。任何未经身份验证的用户也将被拒绝访问该网站的其余部分。在测试时,我发现一旦用户成功通过身份验证,如果他们使用直接URL到" /"或localhost:8080进行测试,而不是像以前那样重定向到登录页面他们会在未经过身份验证时返回包含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 App的新手,所以非常感谢任何帮助!
答案 0 :(得分:1)
对于有类似问题的人,我通过更改解决了我的问题:
.anyRequest().authenticated()
到
.anyRequest().denyAll().
一旦用户通过身份验证,他们就能够对我们的Web应用程序发出任何请求。通过使用denyAll,我们可以阻止我们的antmatchers中未指定的所有请求。我还修改过这样的反对者:
.antMatchers("/webapp/business").hasRole("USER")
到
.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
为了以防万一,我确保将任何请求重新路由到&#34; /&#34;到我们的登录页面&#34; / login&#34;。