尽管身份验证完成,为啥 SpringBoot Security 不向 REST 客户端返回任何响应
Posted
技术标签:
【中文标题】尽管身份验证完成,为啥 SpringBoot Security 不向 REST 客户端返回任何响应【英文标题】:Why doesn't SpringBoot Security return any response to REST client although the authentication is done尽管身份验证完成,为什么 SpringBoot Security 不向 REST 客户端返回任何响应 【发布时间】:2020-03-06 15:15:54 【问题描述】:我正在尝试在 SpringBoot 中使用 REST API 实现 JWT 身份验证。当我调试我的代码时,我看到 JWT Authenticator 工作正常,但我看不到 Spring Security 框架调用了 JWT 授权代码,并且没有响应发送到我的 REST 客户端。以下是我认为与我的问题有关的代码的一些部分。
我认为我的请求在 Spring Security 流程中的某个地方丢失了......
WebSecurityConfig
:
@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
JWTAuthenticationFilter
:
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter
public JWTAuthenticationFilter(AuthenticationManager authenticationManager)
setAuthenticationManager(authenticationManager);
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException
if (!HttpMethod.POST.matches(request.getMethod()))
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
try
JsonAuthenticationParser auth =
new ObjectMapper().readValue(request.getInputStream(), JsonAuthenticationParser.class);
System.out.println(auth.username);
System.out.println(auth.password);
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(auth.username, auth.password);
return this.getAuthenticationManager().authenticate(authRequest);
catch (Exception e)
log.warn("Auth failed!!!!!!!!!!!!");
throw new InternalAuthenticationServiceException("Could not parse authentication payload");
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res,
FilterChain chain, Authentication auth) throws IOException, ServletException
String token = Jwts.builder().setSubject(((User) auth.getPrincipal()).getUsername())
.claim("roles", ((User) auth.getPrincipal()).getAuthorities())
.setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes()).compact();
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
System.out.println("Token:"+token);
JWTAuthorizationFilter
public class JWTAuthorizationFilter extends BasicAuthenticationFilter
public JWTAuthorizationFilter(AuthenticationManager authManager)
super(authManager);
@Override
protected void doFilterInternal(
HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws IOException, ServletException
System.out.println("++++++++++++++++++++++++++++AUTHERIZATION doFilterInternal++++++++++++++++++++++");
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request)
System.out.println("++++++++++++++++++++++++++++AUTHERIZATION getAuthentication++++++++++++++++++++++");
【问题讨论】:
【参考方案1】:背景
当您将过滤器添加到过滤器链而不指定顺序 (http.addFilter(...)
) 时,比较器 HttpSecurity
用于确定其在链中的顺序会查看过滤器的父类。 UsernamePasswordAuthenticationFilter
位于 BasicAuthenticationFilter
之前(参见 FilterComparator)。
请求进来,到达JWTAuthenticationFilter
,并在successfulAuthentication()
方法中“结束”。
解决方案
继续JWTAuthenticationFilter
中的过滤器链:
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res,
FilterChain chain, Authentication auth)
throws IOException, ServletException
// ...
chain.doFilter(req, res);
【讨论】:
谢谢,调用chain.doFilter方法后,SpringBoot调用了JWTAuthorizationFilter,但它返回了禁止(http 403)给我的客户端... 您是否为具有 ADMIN 角色的用户使用凭据(因为这是您在配置中指定的)?以上是关于尽管身份验证完成,为啥 SpringBoot Security 不向 REST 客户端返回任何响应的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spring Security 身份验证会导致 CORS 错误
请问我的华为手机为啥不能进行谷歌身份验证(已生成验证码但不能用)?