首页 > 解决方案 > 获取请求中的 401 状态

问题描述

大家好,我正在(spring/angular)应用程序中工作,当我发送 GET 请求进行身份验证时,我收到此错误:我将 angular 5 用于前端,将 spring boot 2/mysql 用于后端

在此处输入图像描述

这是我的春季安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private Environment env;

    @Autowired
    private UserSecurityService userSecurityService;

    private BCryptPasswordEncoder passwordEncoder() {
        return SecurityUtility.passwordEncoder();
    }

    private static final String[] PUBLIC_MATCHERS= {
            "/css/**",
            "/js/**",
            "/image/**",
            "/book/**",
            "/user/**",
    };

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

        http.csrf().disable()
        .cors().disable().
        httpBasic().and().
        authorizeRequests().antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();

    }


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

}

这是我的过滤器:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter{


    public void doFilter(ServletRequest req ,ServletResponse res,FilterChain chain) {

        HttpServletRequest request = (HttpServletRequest)req;

        HttpServletResponse response = (HttpServletResponse)res;


        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Methodes","POST,PUT,GET,OPTIONS,DELETE");
        response.setHeader("Access-Control-Allow-Headers","x-requested-with,x-auth-token");
        response.setHeader("Access-Control-Allow-Max-Age","3600");
        response.setHeader("Access-Control-Allow-Credentials","true");


            if(!request.getMethod().equalsIgnoreCase("OPTIONS")){
                try {
                    chain.doFilter(req, res);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } 

            }
            else {
                System.out.println("preflight");
                response.setHeader("Access-Control-Allow-Methodes","POST,GET,DELETE");
                response.setHeader("Access-Control-Allow-Max-Age","3600");
                response.setHeader("Access-Control-Allow-Headers","authorization,content-type,x-auth-token,access-control-request-headers,access-control-request-method,accept,origin,x-requested-with");
                response.setStatus(HttpServletResponse.SC_OK);

            }

    }

    public void init(FilterConfig filterConfig) {

    }

    public void destroy() {

    }


}

这是我的控制器:

@RequestMapping("/token")
    public Map<String, String> token(HttpSession session,HttpServletRequest request){

        String remoteHost=request.getRemoteHost();
        int portNumber=request.getRemotePort();
        System.out.println(remoteHost +":"+portNumber);
        System.out.println(request.getRemoteAddr());        
        return Collections.singletonMap("token",session.getId());
    }

这是我的 Angular 5 服务:

@Injectable()
export class LoginService {

  constructor(private http: HttpClient) {

  }
  sendCredential(username: string, password: string) {
    let url = "http://localhost:8080/token";
    let encodedCredentials = btoa(username + ':' + password);
    let basicHeader = "Basic " + encodedCredentials;
    let headers=new HttpHeaders({
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': basicHeader
      });

    return this.http.get(url,{headers:headers});

  }
}

标签: springangularrestspring-boot

解决方案


请允许来自您的安全配置类的 OPTIONS 请求,因为客户端(角度)首先发送 OPTIONS 请求以验证服务器是否允许自定义添加的标头,然后将实际请求发送到服务器。

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .cors().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers(PUBLIC_MATCHERS).permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();

    }

注意:请注意,因为您使用的是Bcrypt密码,但Basic Http会发送Base64编码密码,因此这可能会出现问题,因此请检查UserSecurityService.


推荐阅读