我正在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行之前,这段代码运行良好,只要用户属于必需组的一部分,它仍然可以正常工作。
我还没有提供此处调用的某些方法的源代码,如果有人愿意,我很乐意将其粘贴。我猜想一个很了解这些知识的人会立即发现问题。
任何建议将不胜感激。
答案 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页面,在该页面上添加了一个部分,用于检测请求属性的存在。瞧,我已经准备好了。