axios 中定义的标头内容类型不起作用
我在将登录前端逻辑(Vue3 + Axios)集成到我的 Java API(使用 Spring Security)时遇到了一些麻烦。
我收到以下错误:
com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 0]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4344) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4189) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3242) ~[jackson-databind-2.10.2.jar:2.10.2]
at br.com.preferencialsaude.app.JWTLoginFilter.attemptAuthentication(JWTLoginFilter.java:35) ~[classes/:na]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
调试时,我发现我的 HttpServletRequest 中不存在“Content-Type: application/json”标头,但问题是我实际上正在设置它 在我的 axios 客户端中。
当我从邮递员发出请求时,它工作正常,但是当我尝试从前端应用程序发出请求时,我收到了之前的错误。
我以为这可能是浏览器的问题,但在任何浏览器中都会出现同样的可怕错误。我什至尝试使用 JS Fecth API 发出请求,但行为保持不变。
当我从浏览器发出请求时的 MimeHeaderFields:
host, connection, accept, access-control-request-method, access-control-request-headers,
origin,user-agent, sec-fetch-mode, sec-fetch-site, sec-fetch-dest, referer,
accept-encoding, accept-language
如您所见,没有 Content-Type
,但当我从邮递员发出请求时它会出现。
这是我的客户端代码:
async handleSubmit () {
const response = await axios.post('http://localhost:8080/ws/login',
{ username: this.login, password: this.senha }, {
headers: {
'Content-Type': 'application/json',
}
});
console.log(response.data)
localStorage.setItem('token', response.data.token);
}
这是我的后端 Java 过滤器:
import java.io.IOException;
import java.util.Collections;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
import br.com.preferencialsaude.app.model.AccountCredentials;
import br.com.preferencialsaude.app.service.TokenAuthenticationService;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
protected JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
//here is where I get the error, due to the lack of Content-Type header
AccountCredentials credentials = new ObjectMapper().readValue(request.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken userAuthData =
new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), Collections.emptyList());
return getAuthenticationManager().authenticate(userAuthData);
}
这是我在邮递员中得到的结果:
{"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0aGFseXMiLCJleHAiOjE2NDYzMzM2OTB9.5wYyYs6jwhIsxob99Ubx4b64jIIMjVKXf0bZ_ZS_zhkPtrK0KOgKxOgy0HgxlEdV_F5DTwOeDooqVRouEuAqEA"}
status 代码 200
这是我的 WebSecurityConfig 类:
package br.com.preferencialsaude.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import br.com.preferencialsaude.app.service.MyUserDetailsService;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
private MyUserDetailsService userDetailsService;
public WebSecurityConfig(MyUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/", "/login").permitAll()
.antMatchers(HttpMethod.POST, "/ws/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JWTLoginFilter("/ws/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/gerenciador/home", true)
.usernameParameter("usuario")
.passwordParameter("senha")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/gerenciador/logout"))
.logoutSuccessUrl("/gerenciador/login").and().exceptionHandling()
.accessDeniedPage("/error");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/resources/**", "/static/**", "/css/**", "/js/**", "/imagens/**",
"/webfonts/**", "/jasper/**", "/contratos/**",
"/v2/api-docs", "/swagger-resources/**", "/configuration/ui", "/swagger-ui.html", "/webjars/**",
"/procedimento/**", "/procedimento/**/**", "/credenciamento/empresa/**", "/credenciamento/pessoa/**",
"/credenciamento/farmacia/**", "/buscaCep", "/plano/**", "/contrato/empresa/**",
"/contrato/pessoa-fisica/**", "/rede-credenciada/**", "/ws/rede-credenciada/**", "/ws/endereco/**",
"/ws/procedimentos/**", "/ws/recuperar-senha/**", "/api/cupons-venda/**", "/atendimento/**",
"/termos", "/convenio/**", "/ws/agendamento/**", "/ws/consulta/**", "/ws/notificacoes/**", "/ws/avaliacao/**",
"/ws/imagens/**", "/actuator/**", "/api/enderecos/**", "/api/cadastros-clientes/**", "/api/cidades/**",
"/api/planos/**", "/api/especialidades-saude/consultas/**", "/api/rede-atendimento/**"
);
}
}
这是我的 JWTLoginFilter:
package br.com.preferencialsaude.app;
import java.io.IOException;
import java.util.Collections;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
import br.com.preferencialsaude.app.model.AccountCredentials;
import br.com.preferencialsaude.app.service.TokenAuthenticationService;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
protected JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(request.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken userAuthData =
new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), Collections.emptyList());
return getAuthenticationManager().authenticate(userAuthData);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain, Authentication auth) throws IOException, ServletException {
TokenAuthenticationService.addAuthentication(response, auth.getName());
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.clearContext();
TokenAuthenticationService.failAuthentication(response);
}
}
您是否遇到过类似的问题?我很感激任何帮助!
I'm having a little trouble to integrate my login frontend logics (Vue3 + Axios) to my Java API (with Spring Security).
I'm getting the following error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 0]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4344) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4189) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3242) ~[jackson-databind-2.10.2.jar:2.10.2]
at br.com.preferencialsaude.app.JWTLoginFilter.attemptAuthentication(JWTLoginFilter.java:35) ~[classes/:na]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
While debugging I've found out that no "Content-Type: application/json" header is present in my HttpServletRequest, but the problem is that I'm actually setting it in my axios client.
When I make the request from postman, it works fine, but when I try to make from my frontend app, I get the previous error.
I thought it could be the browser, but it ends up in the same freaking error in any browser. I've even tried to make the request with JS Fecth API, but the behavior remains the same.
The MimeHeaderFields when I make the request from browser:
host, connection, accept, access-control-request-method, access-control-request-headers,
origin,user-agent, sec-fetch-mode, sec-fetch-site, sec-fetch-dest, referer,
accept-encoding, accept-language
As you can see, there's no Content-Type
, but it is present when I make request from postman.
Here is my client-side code:
async handleSubmit () {
const response = await axios.post('http://localhost:8080/ws/login',
{ username: this.login, password: this.senha }, {
headers: {
'Content-Type': 'application/json',
}
});
console.log(response.data)
localStorage.setItem('token', response.data.token);
}
And here is my backend Java filter:
import java.io.IOException;
import java.util.Collections;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
import br.com.preferencialsaude.app.model.AccountCredentials;
import br.com.preferencialsaude.app.service.TokenAuthenticationService;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
protected JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
//here is where I get the error, due to the lack of Content-Type header
AccountCredentials credentials = new ObjectMapper().readValue(request.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken userAuthData =
new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), Collections.emptyList());
return getAuthenticationManager().authenticate(userAuthData);
}
And this is the result I get in postman:
{"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0aGFseXMiLCJleHAiOjE2NDYzMzM2OTB9.5wYyYs6jwhIsxob99Ubx4b64jIIMjVKXf0bZ_ZS_zhkPtrK0KOgKxOgy0HgxlEdV_F5DTwOeDooqVRouEuAqEA"}
with status code 200
Here is my WebSecurityConfig class:
package br.com.preferencialsaude.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import br.com.preferencialsaude.app.service.MyUserDetailsService;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
private MyUserDetailsService userDetailsService;
public WebSecurityConfig(MyUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/", "/login").permitAll()
.antMatchers(HttpMethod.POST, "/ws/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JWTLoginFilter("/ws/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/gerenciador/home", true)
.usernameParameter("usuario")
.passwordParameter("senha")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/gerenciador/logout"))
.logoutSuccessUrl("/gerenciador/login").and().exceptionHandling()
.accessDeniedPage("/error");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/resources/**", "/static/**", "/css/**", "/js/**", "/imagens/**",
"/webfonts/**", "/jasper/**", "/contratos/**",
"/v2/api-docs", "/swagger-resources/**", "/configuration/ui", "/swagger-ui.html", "/webjars/**",
"/procedimento/**", "/procedimento/**/**", "/credenciamento/empresa/**", "/credenciamento/pessoa/**",
"/credenciamento/farmacia/**", "/buscaCep", "/plano/**", "/contrato/empresa/**",
"/contrato/pessoa-fisica/**", "/rede-credenciada/**", "/ws/rede-credenciada/**", "/ws/endereco/**",
"/ws/procedimentos/**", "/ws/recuperar-senha/**", "/api/cupons-venda/**", "/atendimento/**",
"/termos", "/convenio/**", "/ws/agendamento/**", "/ws/consulta/**", "/ws/notificacoes/**", "/ws/avaliacao/**",
"/ws/imagens/**", "/actuator/**", "/api/enderecos/**", "/api/cadastros-clientes/**", "/api/cidades/**",
"/api/planos/**", "/api/especialidades-saude/consultas/**", "/api/rede-atendimento/**"
);
}
}
And here is my JWTLoginFilter:
package br.com.preferencialsaude.app;
import java.io.IOException;
import java.util.Collections;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
import br.com.preferencialsaude.app.model.AccountCredentials;
import br.com.preferencialsaude.app.service.TokenAuthenticationService;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
protected JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(request.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken userAuthData =
new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), Collections.emptyList());
return getAuthenticationManager().authenticate(userAuthData);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain, Authentication auth) throws IOException, ServletException {
TokenAuthenticationService.addAuthentication(response, auth.getName());
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.clearContext();
TokenAuthenticationService.failAuthentication(response);
}
}
Have you ever faced a similar problem? I appreciate any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想出了如何通过在 WebSecurityConfig 文件中添加一些 CORS 配置来解决此问题。
问题根本不在于 Content-Type 标头,而在于 Spring Security 阻止了 OPTIONS 请求。
这是我添加的用于解决问题的代码片段
在此 CORS 配置教程内的评论中找到了此代码: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
如果您想接受来自所有来源的请求,只需将 setAllowedOrigins() 替换为 addAllowedOrigin("*") 即可,因为按照我配置它的方式(如上面的代码所示),我无法从邮递员或除我定义的来源之外的任何其他来源登录。
I figured it out how to resolve this by adding some CORS configuration in my WebSecurityConfig file.
The problem wasn't the Content-Type Header at all, but Spring Security that was blocking OPTIONS requests.
This is the piece of code I added to solve the issue
Found this code in a comment inside this CORS configuration tutorial: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
If you want to accept requests from all origins, just replace the
setAllowedOrigins() with addAllowedOrigin("*")
, since the way I configured it, as in the code above, I cannot login from postman, or any other origins except the ones I defined.