spring-security Spring Security Jwt标记在请求表单Angular 时允许所有选项方法

0sgqnhkj  于 2022-11-11  发布在  Spring
关注(0)|答案(2)|浏览(141)

我不知道是怎么回事,我在网上到处查了一下,似乎和我的情况一样,但我遇到了这个问题:
我正在使用带有Angular拦截器的HttpClient请求My Angular应用程序setHeader,因为我的Java Rest API正在使用JWT进行身份验证,并且在标头中需要一个标记,这样它将获取并验证用户请求,因为Angular拦截器无法正常工作。我在Java端获取空值作为标记,并收到一个错误。请帮助我解决此问题。

最后,我发现可能是Spring安全性的问题,因为我调试并发现选项请求所有过滤器,而它没有头,因此它显示标记并抛出异常,如果选项方法请求绕过并允许,则可能是我的问题将解决

Sping Boot 安全配置

package com.techprimers.security.jwtsecurity.config;

import com.techprimers.security.jwtsecurity.security.JwtAuthenticationEntryPoint;
import com.techprimers.security.jwtsecurity.security.JwtAuthenticationProvider;
import com.techprimers.security.jwtsecurity.security.JwtAuthenticationTokenFilter;
import com.techprimers.security.jwtsecurity.security.JwtSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.Collections;

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

    @Autowired
    private JwtAuthenticationProvider authenticationProvider;
    @Autowired
    private JwtAuthenticationEntryPoint entryPoint;

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Collections.singletonList(authenticationProvider));
    }

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilter() {
        JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
        return filter;
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests().antMatchers("**/rest/**").authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(entryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();

    }
}

角拦截器代码

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available

            console.log("i am inside");

            request = request.clone({
                setHeaders: {
                    Accept: 'application/json',
                    Authorization: `Bearer ${localStorage.getItem('token')}`
                }
            });

        return next.handle(request);
    }
}

Angular 服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ServiceService {

  constructor(private http: HttpClient) { }

  api_user_url = 'http://localhost:8095';

  getAllApiUsers(): Observable<any> {
    return this.http.get(this.api_user_url + "/allUser");
  }

  setUserLogin(obj):Observable<any>{

    return this.http.post(this.api_user_url +"/login", obj);
  }
}

调用方法

public getAllUserList() {

    console.log("I am calling");

    this.service.getAllApiUsers()
      .subscribe(data => {
        this.alluser = data;
        console.log(data);

      })
  }

浏览器网络

令牌的本地存储

浏览器控制台错误消息

Sping Boot Java控制台错误

e37o9pze

e37o9pze1#

我认为您的问题的正确答案在JwtSecurityConfig中。您需要添加OPTIONS调用,以便允许在不请求auth标记的情况下传递JWT安全性。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.csrf().disable()
            .authorizeRequests()
            // Add this line to your code
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("**/rest/**").authenticated()
            .and()
            .exceptionHandling().authenticationEntryPoint(entryPoint)
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    http.headers().cacheControl();

}
s8vozzvw

s8vozzvw2#

Angular 拦截器看起来不错,但在您的浏览器控制台有CORS policy错误。您的Angular 应用程序运行在端口4200上,而您的后端运行在8095上(不同的主机)。
我不知道spring-boot,但是在查看文档之后,您应该向后端应用程序添加一些cors策略(对于生产和开发环境是不同的):

您可以在此处阅读更多信息:https://spring.io/guides/gs/rest-service-cors/
现在,您对/allUser的请求未发送......在消除CORS问题后,一切都应正常工作

相关问题