角度响应标头读取错误,响应时为空对象



我的后端是春天的,前端是有角度的。我在访问授权标头时遇到问题。在poster中,如果我使用正确的数据ping localhost:8080/login,我会获得成功授权,但在我的应用程序中,当我尝试使用httpclient localhost:8080.login发布正确的数据时,我会得到成功响应,但标头中没有令牌,标头为空。

Angular AuthService:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class AuthService {
/** Data */
token!: string;
logged = false;
/** Constructor */
constructor(private http: HttpClient) { }
/** Authentiacate User */
login(username: string, password: string): void {
const credentials: LoginCredentials = {
username,
password
};
this.http.post('http://localhost:8080/login',
JSON.stringify(credentials), { observe: 'response' }).subscribe(res => {
// Not works... Authorization header is null object
console.log('Authorized success!' + res.headers.get('Authorization'));
this.logged = true;
},
(error: HttpErrorResponse) => {
console.log('Nie udana autoryzacja! KOD BLEDU: ' + error.status);
});
}
}
/** LoginCredentials */
interface LoginCredentials {
username: string;
password: string;
}

Spring AuthorizationFilter、SuccessHandler、SecurityConfig

package com.revo.ToDoList.handler;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.revo.ToDoList.config.SecurityConfig;
import com.revo.ToDoList.model.User;
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

/*
* On success authentication add token to header
*/

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
String token = JWT.create().withSubject(((User) authentication.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + SecurityConfig.expirationTime)).sign(Algorithm.HMAC256(SecurityConfig.secret));
response.addHeader("Authorization", "Bearer " + token);
}
}
package com.revo.ToDoList.filter;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.revo.ToDoList.model.LoginCredentials;
public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

/*
* Data
*/

private ObjectMapper objectMapper = new ObjectMapper();
/*
* Auth user
*/

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
LoginCredentials authRequest = objectMapper.readValue(sb.toString(), LoginCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
authRequest.getUsername(), authRequest.getPassword()
);
setDetails(request, token);
return this.getAuthenticationManager().authenticate(token);
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

}
package com.revo.ToDoList.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.revo.ToDoList.filter.JwtAuthorizationFilter;
import com.revo.ToDoList.filter.MyAuthenticationFilter;
import com.revo.ToDoList.handler.MyAuthenticationSuccessHandler;
import com.revo.ToDoList.service.UserService;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

/*
* Data
*/

@Autowired
private UserService userService;
public static final String secret = "ACAB SKURWYSYNY";
public static final long expirationTime=86400000;
/*
* Http Security Rules
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/register").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JwtAuthorizationFilter(super.authenticationManagerBean(), userService), BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
http.cors().disable().csrf().disable();
}

/*
* Auth Manager Configuration
*/

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}

/*
* ENCODER
*/

@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

/*
* My Authentication Filter
*/
private MyAuthenticationFilter authFilter() throws Exception {
MyAuthenticationFilter authFilter = new MyAuthenticationFilter();
authFilter.setAuthenticationSuccessHandler(new MyAuthenticationSuccessHandler());
authFilter.setAuthenticationManager(super.authenticationManager());
authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
return authFilter;
}
}

这看起来像是一个CORS问题。可能您需要设置cors.allowed.headers

<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Origin, Accept, X-Requested-With, Content-Type, Content-Disposition, Access-Control-Request-Method, **Access-Control-Request-Headers**</param-value>
</init-param>

如果是春天,它可能是如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
........
.........
}

我曾经遇到过类似的问题,

您可以尝试将以下内容添加到您的主类中

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:8080");
}
};
}

最新更新