当前位置: 首页 > 知识库问答 >
问题:

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

罗鸿福
2023-03-14

我的后端是spring,前端是Angular。我无法访问授权标头。在postman中,如果我ping localhost:8080/login具有正确的数据,我就会获得成功授权,但是在我的应用程序中,当我尝试用httpclient localhost: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;
}
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;
    }

}

共有1个答案

益光亮
2023-03-14

看起来像是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"));
       ........
       .........
}
 类似资料:
  • 我正在尝试使用角和Spring启动编写登录页面,但我无法阅读角的帖子响应。 表单登录 ts组件 服务身份验证 问题是:我怎样才能得到回复后的标题……我想得到授权

  • 我正在开发angular 7应用程序,但在get请求中遇到了问题。 以下是错误: 这是我的角色服务。ts: 这是组件。输电系统 当服务器向我发送请求的数据时,我不明白这个错误来自哪里。 提前谢谢你!!!

  • 我正在使用nginx和Firebug+FirePHP,当我试图加载页面时,我得到了一个错误: 我们在开发环境中记录了很多东西,我想这就是使用FirePHP时出现问题的原因。在这里阅读了类似的其他问题后,似乎有以下设置之一:

  • 问题内容: 我正在使用RestTemplate.postForObject将信息发布到Web服务。除了结果字符串,我还需要响应头中的信息。有什么办法可以做到这一点? 问题答案: 好吧,我终于明白了。交换方法正是我所需要的。它返回包含完整标头的HttpEntity。

  • 问题内容: 我正在使用api调用,它正在发送一些自定义标头,例如。但是我还不知道如何阅读它们。在函数内部,是一个应该给我所有标头的哈希值的函数,但仅显示标头。有没有办法获取响应头? 问题答案: 自定义标题将在同一域中可见。但是,对于跨域情况,服务器必须发送标头以使自定义标头可见。

  • 问题内容: 如何从WebView获得HTTP标头响应?我找到了半解决方案,但是它是用Objective- C编写的,不能将其转换为Swift(我已经尝试过使用较差的Obj-C知识了)。 Objective-C代码: 该代码将如何看待Swift? 也许现在我们有更好的方法呢?并不总是启用缓存。 问题答案: 迅速 斯威夫特更严格; 您想保护自己免受指针和: 检查实际是否有 检查实际是否有 对响应进行类