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

调用spring rest api时出现CORS未授权的401错误

云慈
2023-03-14

我的rest服务中没有Spring Security实现,当我试图调用rest中的资源时,我面临CORS 401未授权问题。

我对此感到愤怒:

https://www.baeldung.com/spring-security-cors-preflight

https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/html5/#cors

我有两个电话要Rest:

1) 登录

2) 其他

登录功能是基于Shiro的,例如,当我从Postman执行登录,然后尝试调用其他资源时,它就工作了。

当我开始用react实现客户端应用程序时,我的问题就开始了,我试图从fetch javascript方法调用其余部分。我在第一次调用登录时遇到了CORS问题,我通过在控制器中添加@CorsOrigin注释解决了这个问题,但登录成功后,第二次调用在CORS 401上仍然失败。

如果我理解正确,CORS可以通过添加filter t oWebSecurityConfig来解决,但如果我的应用程序是从Postman运行的,那么就没有必要在我的服务器端应用程序中执行这样的更改,我想从客户端解决它。

这让我可以选择在我的请求中传递JSESSIONID,对吧?!我仍然不知道该怎么做...我应该从哪里获取JSESSIONID?我尝试阅读浏览器的cookie,但在那里没有找到它...我尝试从第一次调用登录的响应标头中获取它,但响应为空!

尝试在服务器端使用Spring解决它,但没有成功:

Web安全配置:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {

//        http
//        .cors();
//        .headers().disable();

//      http
//        .authorizeRequests()
//        .requestMatchers(CorsUtils::isCorsRequest).permitAll()
//        .anyRequest().authenticated()
//        .and().httpBasic()
//        .and().addFilterBefore(new WebSecurityCorsFilter(), ChannelProcessingFilter.class);

        http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);

    }
}

WebSecurityCorsFilter:

public class WebSecurityCorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse res = (HttpServletResponse) response;
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
    res.setHeader("Access-Control-Max-Age", "3600");
    res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
    chain.doFilter(request, res);
}

@Override
public void destroy() {
}

}

或CorsFilter(使用其中一个):

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

public CorsFilter () {
    super();
}

@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
    final HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");

    // without this header jquery.ajax calls returns 401 even after successful login and SSESSIONID being succesfully stored.
    response.setHeader("Access-Control-Allow-Credentials", "true");

    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Origin, Content-Type, Version");
    response.setHeader("Access-Control-Expose-Headers", "X-Requested-With, Authorization, Origin, Content-Type");

    final HttpServletRequest request = (HttpServletRequest) req;
    if (!request.getMethod().equals("OPTIONS")) {
        chain.doFilter(req, res);
    } else {
        // do not continue with filter chain for options requests
    }
}

@Override
public void destroy() {

} 

@Override
public void init(FilterConfig filterConfig) throws ServletException {       
}
}

共有1个答案

澹台景辉
2023-03-14

多亏了这个类似的获取问题:https://github.com/github/fetch/issues/386

我终于成功了。所以,总结一下:

1)不需要更改Spring Security Config,除了将此注释添加到控制器之外(您可以将其添加到基本控制器一次,并且都可以从中继承)

@Cross Origin(起源 = " * ", 允许标头 = " * ")

2)从客户端,当使用fetch时,我必须从两个请求(Login和第二个请求)中使用:

凭据:“包括”、//“同源”

(注意使用cors时不要使用凭据的“同源”值)

无需手动设置任何cookie,浏览器应该处理它(如果您需要编写Java客户端,那么就需要它...你可以搜索CookiesManagement java类,你会发现这样的实现)

 类似资料:
  • 我的代码:GoogleCredential凭据 credential.refreshToken() 错误日志: 创建服务号的步骤: 我在凭据中的oauth 2.0中创建了一个Web应用程序 然后我用客户端ID创建了一个服务号 现在我正在使用这个服务号和从它生成的p12证书来验证和创建Google凭据的对象 一旦刷新令牌,我就给了我401例外。 在这种情况下,任何帮助都会受到感激

  • 在jHipster中是否可以实现这一特定功能,以使身份验证能够从浏览器或应用程序(不在jHipster服务器上运行)工作?

  • 我试图测试Firebase Cloud messaging APIs,因为控制台没有提供所有功能(特别是当应用程序在后台时定制通知)。但由于某些原因,我无法让它工作,它总是显示401错误。我调查了出现这种情况的原因,并在重新生成新的服务器密钥后进行了尝试,但错误仍然存在。令人惊讶的是,当我生成一个新的服务器密钥时,它没有反映在Firebase控制台中,它将服务器密钥显示为空。此外,我尝试添加我的I

  • 我是Spring boot和Spring Security的新手,出现以下错误: “错误401未经授权(c.e.l.security.jwt.AuthEntryPointJwt:未经授权的错误:访问此资源需要完全身份验证)” 我试过这个认证 我的问题是,当我成功登录时,我想请求获取用户列表。我发送的请求是一个安全GET请求,它是http://localhost:8084/loginsystem/a

  • Microsoft.Graph REST.API 我试图通过https://graph.microsoft.com/v1.0/me从graph.api获得有关我的信息 我也在这里检查这个其他主题,但我找不到像我一样的错误

  • 实体类 测试代码 控制器 我制作了一个更新DB的Spring启动测试代码示例,但如果执行该代码,测试将失败,并显示以下错误消息。我已经定义了spring。安全使用者名称和