Angular 响应头读取错误,响应时对象为空

weylhg0b  于 2021-07-16  发布在  Java
关注(0)|答案(2)|浏览(313)

我的后端在 Spring ,前端在角。我无法访问授权标头。在 Postman 如果我localhost:8080/login 有正确的数据我得到了成功的授权,但在我的应用程序中,当我试图发布与httpclientlocalhost:8080/login 有了正确的数据,我得到了成功的响应,但是在头中没有标记,头是空的。
身份验证服务:

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;
    }

}
bvjveswy

bvjveswy1#

看起来是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>

如果是Spring,可能是这样的:

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

wdebmtf22#

我也有过类似的问题,
你可以试着把下面的内容加到你的主课上

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

相关问题