自定义登录表单。配置Spring安全性以获取JSON响应

我有一个简单的应用程序,分为两个部分:

  • 后端通过Spring-boot / Spring-security公开REST服务
  • 一个仅包含静态文件的前端。

Nginx服务器接收请求,该服务器监听端口80。

  • 如果请求URL以/ api /开头,则该请求将重定向到后端。
  • 否则,该请求由提供静态文件的nginx处理。

我创建了一个自定义登录表单(在前端部分),并且试图配置Spring-boot服务器。

在很多示例中,我可以看到如何定义“登录成功” URL和“登录错误” URL,但是我不希望Spring-security重定向用户。如果登录成功或HTTP

40x登录失败,我希望Spring-security用HTTP 200回答。

换句话说:我希望后端仅使用JSON回答,而不是HTML。

到目前为止,当我提交登录表单时,请求将被重定向,并获得默认的Spring登录表单作为答案。

我尝试使用.formLogin().loginProcessingUrl("/login");代替loginPage("")

@Configuration

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)

protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()

.withUser("user").password("password").roles("ADMIN");

}

@Override

public void configure(HttpSecurity http) throws Exception {

http

.authorizeRequests()

.anyRequest().authenticated()

.and()

.formLogin()

.loginProcessingUrl("/login");

回答:

感谢M. Deinum和本指南,我找到了解决方案。

首先,登录表单本身存在配置问题。由于后端将context-

path设置为/api,所以自定义表单应该已经向提交了表单参数,/api/login但是实际上我正在向提交数据/api/login/(请注意/最后的内容)。

结果,我在不知不觉中试图访问受保护的资源!因此,该请求由默认AuthenticationEntryPoint值处理,默认行为是将用户重定向到登录页面。

作为解决方案,我实现了一个自定义AuthenticationEntryPoint:

private AuthenticationEntryPoint authenticationEntryPoint() {

return new AuthenticationEntryPoint() {

@Override

public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {

httpServletResponse.getWriter().append("Not authenticated");

httpServletResponse.setStatus(401);

}

};

}

然后在配置中使用它:

http

.exceptionHandling()

.authenticationEntryPoint(authenticationEntryPoint())

我对其他处理程序也做了同样的事情:

@Configuration

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)

protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()

.withUser("user").password("password").roles("ADMIN");

}

@Override

public void configure(HttpSecurity http) throws Exception {

http

.authorizeRequests()

.anyRequest().authenticated()

.and()

.formLogin()

.successHandler(successHandler())

.failureHandler(failureHandler())

.and()

.exceptionHandling()

.accessDeniedHandler(accessDeniedHandler())

.authenticationEntryPoint(authenticationEntryPoint())

.and()

.csrf().csrfTokenRepository(csrfTokenRepository()).and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)

;

}

private AuthenticationSuccessHandler successHandler() {

return new AuthenticationSuccessHandler() {

@Override

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

httpServletResponse.getWriter().append("OK");

httpServletResponse.setStatus(200);

}

};

}

private AuthenticationFailureHandler failureHandler() {

return new AuthenticationFailureHandler() {

@Override

public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {

httpServletResponse.getWriter().append("Authentication failure");

httpServletResponse.setStatus(401);

}

};

}

private AccessDeniedHandler accessDeniedHandler() {

return new AccessDeniedHandler() {

@Override

public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {

httpServletResponse.getWriter().append("Access denied");

httpServletResponse.setStatus(403);

}

};

}

private AuthenticationEntryPoint authenticationEntryPoint() {

return new AuthenticationEntryPoint() {

@Override

public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {

httpServletResponse.getWriter().append("Not authenticated");

httpServletResponse.setStatus(401);

}

};

}

private Filter csrfHeaderFilter() {

return new OncePerRequestFilter() {

@Override

protected void doFilterInternal(HttpServletRequest request,

HttpServletResponse response, FilterChain filterChain)

throws ServletException, IOException {

CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class

.getName());

if (csrf != null) {

Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");

String token = csrf.getToken();

if (cookie == null || token != null

&& !token.equals(cookie.getValue())) {

cookie = new Cookie("XSRF-TOKEN", token);

cookie.setPath("/");

response.addCookie(cookie);

}

}

filterChain.doFilter(request, response);

}

};

}

private CsrfTokenRepository csrfTokenRepository() {

HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();

repository.setHeaderName("X-XSRF-TOKEN");

return repository;

}

}

以上是 自定义登录表单。配置Spring安全性以获取JSON响应 的全部内容, 来源链接: utcz.com/qa/397275.html

回到顶部