Angular 6 Http拦截器,未修改请求标头 [英] Angular 6 Http Interceptors, request headers not modified

查看:69
本文介绍了Angular 6 Http拦截器,未修改请求标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个拦截器,向客户端发送的每个请求添加一个授权标头,这是代码:

I created an interceptor to add an authorization header to each request sent by the client, here is the code :

import { HttpInterceptor, HttpRequest, HttpHandler, HttpHeaderResponse, HttpSentEvent, HttpProgressEvent, HttpResponse, HttpUserEvent, HttpEvent, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
import { Injectable } from "@angular/core";

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(localStorage.getItem('jwtToken'));
        if(localStorage.getItem('jwtToken')){
            const request = req.clone({
                setHeaders: {
                    Authorization: `bearer ${localStorage.getItem('jwtToken')}`
                }
            });
            console.log(request.headers.get("Authorization"));
            return next.handle(request);
        }
        return next.handle(req);
    }
}

发送请求时,将调用函数拦截,并使用变量"request"中的令牌值正确设置授权标头,如您所见: 令牌控制台屏幕截图

When a request is sent the function intercept is called and the authorization header is correclty set with the token value in the variable "request" as you can see there : token console screenshot

但是授权标头未出现在我的浏览器发送的请求中:网络请求标头,后端无法解析令牌.

But the authorization header doesn't appear in the request sent by my browser : network request headers and the backend cannot resolve the token.

你知道为什么吗?

这是我的弹簧配置:

WebSecurityConfig.java

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

public final static String AUTHORIZATION_HEADER = "Authorization";

@Autowired
UserService userService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(getProvider());
}

@Bean
public JwtTokenFilter jwtAuthenticationFilter() {
    return new JwtTokenFilter();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    .csrf()
        .disable()
    .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and()
    .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
    .authorizeRequests()
        .antMatchers("/auth/**")
            .permitAll()
        .anyRequest()
            .authenticated();
}

@Bean
public AuthenticationProvider getProvider() {
    AppAuthProvider provider = new AppAuthProvider();
    provider.setUserDetailsService(userService);
    return provider;
}

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

}

CorsConfig.java

CorsConfig.java

@Configuration
public class CorsConfiguration {

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

}

推荐答案

您的问题出在后端服务中.出于安全原因,默认情况下仅接受某些标头,而其他标头将被忽略.

Your problem resides into backend services. For security reasons by default only some headers are accepted, the others are ignored.

要解决您的问题,您需要设置自定义接受的标题. Authorization标头,即使就像JWT的标准一样,也被视为自定义标头.

To fix your problem you need to setup custom accepted headers. Authorization header, even if is like a standard for JWT, is considered a custom header.

我可以举一个我的Spring Security配置示例:

I can give you an example of my Spring Security configuration:

@Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

注意该行

config.addAllowedHeader("*");

这意味着我的REST服务接受客户端发送的所有可能的标头. 显然,这不是一个很好的配置,应限制所允许的标头和其他内容以使其符合您的需求.

That means that my REST services accept all possible headers sent by the client. Obviously it's not a good configuration, you should limit allowed headers and other things to match your needs, as restricted as is possible.

很明显,如果您不使用Spring Security,则需要找到使用您的语言/框架进行相同操作的方法.

Obviously if you don't use Spring Security you need to find the way to do the same thing with yout language/framework.

这是我的SecurityConfig.java.与您的有点不同. 试试这个,让我知道

This is my SecurityConfig.java It's a bit different from yours. Try this and let me know

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private WLUserDetailsService userDetailsService;

    @Value("${jwt.header}")
    private String tokenHeader;

    @Value("${jwt.route.authentication.path}")
    private String authenticationPath;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoderBean());
    }

    @Bean
    public PasswordEncoder passwordEncoderBean() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // we don't need CSRF because our token is invulnerable
                .csrf().disable()

                // TODO adjust CORS management
                .cors().and()

                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

                // don't create session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

                .authorizeRequests()

                .antMatchers("/auth/**").permitAll()
                .anyRequest().authenticated();

        // Custom JWT based security filter
        JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
        httpSecurity
                .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

//        // disable page caching
//        httpSecurity
//                .headers()
//                .frameOptions().sameOrigin()  // required to set for H2 else H2 Console will be blank.
//                .cacheControl();
    }

    @Override
    public void configure(WebSecurity web) {
        // AuthenticationTokenFilter will ignore the below paths
        web
                .ignoring()
                .antMatchers(
                        HttpMethod.POST,
                        authenticationPath
                )

                // allow anonymous resource requests
                .and()
                .ignoring()
                .antMatchers(
                        HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/favicon.ico",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js"
                );
    }


    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
//        config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
//                "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

}

这篇关于Angular 6 Http拦截器,未修改请求标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆