Reactjs Can';t从Axios request向Spring security oauth2后端发出成功的授权请求

Reactjs Can';t从Axios request向Spring security oauth2后端发出成功的授权请求,reactjs,spring-security,oauth-2.0,axios,spring-security-oauth2,Reactjs,Spring Security,Oauth 2.0,Axios,Spring Security Oauth2,嗨,我有个邮递员的请求 如何在Reactjs axios中发出相同的请求 executeAuthenticationService(username, password) { return axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`, { headers: { Authorization:

嗨,我有个邮递员的请求

如何在Reactjs axios中发出相同的请求

executeAuthenticationService(username, password) {
        return axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
            { headers: { Authorization: 'Basic ' + window.btoa('my-trusted-client : secret') } } )            
            .catch(
                (error) => {
                    console.log('error: ' + error);
                }
            );
    }

我试过上面的那个,但不起作用。 谢谢

=============更新:==============

我已经按照你的建议删除了空格。当谈到window.btoa时,没有空格的转换似乎是准确的,但我仍然无法让它工作

使用此代码:

executeAuthenticationService(username, password) {
        return axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
            { 
                headers: 
                { 
                    Authorization: 'Basic ' + window.btoa('my-trusted-client:secret'),
                    "Content-Type": "application/json"
                } 
            })            
            .catch(
                (error) => {
                    console.log('error: ' + error);
                }
            );
    }
我甚至将授权标头硬编码为:

Authorization: "Basic bXktdHJ1c3RlZC1jbGllbnQ6c2VjcmV0",
甚至尝试过:

"Authorization": "Basic bXktdHJ1c3RlZC1jbGllbnQ6c2VjcmV0",
不起作用,授权标头将不会出现在请求中

我在我的Chrome网络选项卡中看到:

我发现我可以在axios中添加身份验证配置,所以我尝试了以下方法:

executeAuthenticationService(username, password) {
        return axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
            { 
                headers: 
                {                     
                    "Content-Type": "application/json"
                }, 

                auth: {
                    username: 'my-trusted-client',
                    password: 'secret'
                }
            })            
            .catch(
                (error) => {
                    console.log('error: ' + error);
                }
            );
    }
仍然没有授权标头。。。请帮忙。谢谢

=============更新2==============

我要补充一些信息

我的Springboot配置如下:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowCredentials(true)               
                .allowedHeaders("Authorization", "Cache-Control", "Content-Type", "Accept", "X-Requested-With", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
                .exposedHeaders("Access-Control-Expose-Headers", "Authorization", "Cache-Control", "Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
                .allowedMethods("GET", "OPTIONS", "POST", "PUT", "DELETE", "PATCH");
    }
}
我使用的最后一个reactJS请求是:

executeAuthenticationService(username, password) {
        return axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
            { 
                headers: 
                {                     
                    "Content-Type": "application/json"
                }, 

                auth: {
                    username: 'my-trusted-client',
                    password: 'secret'
                }
            })            
            .catch(
                (error) => {
                    console.log('error: ' + error);
                }
            );
    }
当我从登录表单中单击“提交”按钮时

我从Chrome标签上得到了这个(全部内容):

然后我在我的Java控制台上看到:

2019-07-11 06:40:47.008 DEBUG 8068 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for OPTIONS "/error?grant_type=password&username=bill&password=abc123", parameters={masked}
2019-07-11 06:40:47.009 DEBUG 8068 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public void org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$EmptyHandler.handle()
2019-07-11 06:40:47.010 DEBUG 8068 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 401

我不知道我还错过了什么。 请帮忙。 非常感谢。

试试这个(删除空格):

试试这个(删除空格):

您可以尝试以下方法:

axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
        {
          headers: {
            Authorization: "Basic " + window.btoa("my-trusted-client : secret"),
            "Content-Type": "application/json",
          },
        }
      )
      .then(resp => {})
      .catch(error => {
        console.log("error: " + error);
      });
您可以尝试以下方法:

axios.get(`${API_URL}/oauth/token?grant_type=password&username=${username}&password=${password}`,
        {
          headers: {
            Authorization: "Basic " + window.btoa("my-trusted-client : secret"),
            "Content-Type": "application/json",
          },
        }
      )
      .then(resp => {})
      .catch(error => {
        console.log("error: " + error);
      });
您可以尝试设置所有请求的标题


您可以尝试为所有请求设置标题

可能是您缺少访问控制允许方法选项的方法吗

这意味着在生成整个请求之前,您可能会被拒绝


或者可能禁用您的选项请求作为授权的一部分,类似于此处所做的操作:

您是否缺少访问控制允许方法中选项的方法

这意味着在生成整个请求之前,您可能会被拒绝


或者可能会禁用您的选项请求作为授权的一部分,类似于此处所做的操作:

在使用Spring和Axios玩basic auth时,为了解决这些问题,我失去了生活的欲望

在尝试了几乎所有的东西之后,甚至像您这样的配置,我为我的用例找到了一个解决方案,它也可以是您的

Axios请求

我像这样使用Axios进行请求,请注意有一个auth参数:

  async removeAnexo(uuidAnexo, successCallback, errorCallback) {
    const credentials = JSON.parse(Cookies.get("credentials"));

    const axiosRequest = axios.create({
      baseURL: serverUrl,
      auth: {
        username: credentials.username,
        password: credentials.password
      },
      headers: {
        "Content-Type": "application/json"
      }
    });
    await axiosRequest
      .post("processos/anexo/" + uuidAnexo + "/remove")
      .then(res => {
        if (res.status === 200) {
          successCallback();
          return res;
        }
      })
      .catch(error => {
        errorCallback(error);
      });
  }
弹簧配置

  • 您需要有一个身份验证入口点,以便在飞行前向端点发出选项请求时,在发出您请求的实际请求之前公开一些必要的头
  • import java.io.IOException;
    导入javax.servlet.ServletException;
    导入javax.servlet.http.HttpServletRequest;
    导入javax.servlet.http.HttpServletResponse;
    导入org.springframework.http.HttpHeaders;
    导入org.springframework.http.HttpMethod;
    导入org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
    导入org.springframework.stereotype.Component;
    @组成部分
    公共类AuthEntryPoint扩展了基本身份验证入口点{
    @凌驾
    公共无效开始(HttpServletRequest请求,HttpServletResponse响应,
    org.springframework.security.core.AuthenticationException(验证异常)
    抛出IOException、ServletException{
    if(HttpMethod.OPTIONS.matches(request.getMethod())){
    response.setStatus(HttpServletResponse.SC_OK);
    response.setHeader(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u ORIGIN,request.getHeader(HttpHeaders.ORIGIN));
    response.setHeader(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u HEADERS,request.getHeader(HttpHeaders.ACCESS\u CONTROL\u request\u HEADERS));
    response.setHeader(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u方法,request.getHeader(HttpHeaders.ACCESS\u CONTROL\u request\u方法));
    response.setHeader(HttpHeaders.ACCESS\u CONTROL\u EXPOSE\u HEADERS,“*”;
    response.setHeader(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u凭证,“true”);
    }否则{
    response.senderro(HttpServletResponse.SC_未经授权,authException.getMessage());
    }
    }
    @凌驾
    public void afterPropertieSet()引发异常{
    此.setRealmName(“simplerelam”);
    super.afterPropertiesSet();
    }
    }
    
  • 然后您需要提供一个定制的过滤器,一个cors过滤器,也可以公开 SessionManagementFilter所需的几个标题
  • import java.io.IOException;
    导入javax.servlet.Filter;
    导入javax.servlet.FilterChain;
    导入javax.servlet.FilterConfig;
    导入javax.servlet.ServletException;
    导入javax.servlet.ServletRequest;
    导入javax.servlet.ServletResponse;
    导入javax.servlet.http.HttpServletRequest;
    导入javax.servlet.http.HttpServletResponse;
    导入org.springframework.stereotype.Component;
    @组成部分
    公共类CorsFilter实现过滤器{
    @凌驾
    public void init(FilterConfig FilterConfig)抛出ServletException{
    }
    @凌驾
    public void doFilter(ServletRequest ServletRequest、ServletResponse ServletResponse、FilterChain FilterChain)
    抛出IOException、ServletException{
    HttpServletResponse=(HttpServletResponse)servletResponse;
    HttpServletRequest=(HttpServletRequest)servletRequest;
    response.setHeader(“访问控制允许原点”),request.getHeader(“原点”);
    setHeader(“访问控制允许方法”、“获取、发布、删除、放置、选项”);
    response.setHeader(“访问控制允许头”,“*”);
    setHeader(“访问控制允许凭据”,“true”);
    
      async removeAnexo(uuidAnexo, successCallback, errorCallback) {
        const credentials = JSON.parse(Cookies.get("credentials"));
    
        const axiosRequest = axios.create({
          baseURL: serverUrl,
          auth: {
            username: credentials.username,
            password: credentials.password
          },
          headers: {
            "Content-Type": "application/json"
          }
        });
        await axiosRequest
          .post("processos/anexo/" + uuidAnexo + "/remove")
          .then(res => {
            if (res.status === 200) {
              successCallback();
              return res;
            }
          })
          .catch(error => {
            errorCallback(error);
          });
      }