springboot+spring-security+ajax+前后端分离解决Authorization请求头跨域问题

security+ajax+前后端分离解决Authorization请求头跨域问题

背景

后端采用 springboot+spring-security+oauth2开发
前台采用纯静态页面的形式开发。()
以此做到前后端分离。采用token的形式做无状态登录。为以后业务扩张的分布式扩展做准备。

问题

前后端分离第一个要解决的是跨域问题。为此我再后台起了一个bean

	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.web.cors.CorsConfiguration;
	import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
	import org.springframework.web.filter.CorsFilter;

	@Configuration
	public class ConfigurationBeans {

    @Bean
	    public CorsFilter corsFilter() {
	        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
	        final CorsConfiguration corsConfiguration = new CorsConfiguration();
	        corsConfiguration.addAllowedOrigin("*");
	        corsConfiguration.setAllowCredentials(true);
	        corsConfiguration.addAllowedHeader("*");
	        corsConfiguration.addAllowedMethod("*");
	        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
	        return new CorsFilter(urlBasedCorsConfigurationSource);
	    }
	}

sercurity配置也得加上这段代码

protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf()
                .disable();
        //下面是http其它配置项
}

附上ajax代码

	var data = getData();
	var auth = getToken();
	var returnData = null;
	 $.ajax({
      type: api.type,
      url: webDomain + api.url,
      data: data,
      async: false,
      contentType: false,
      processData: false,
      beforeSend : function(request) {
        request.setRequestHeader("Authorization",auth);
      },
      success: function (result) {
        console.log(2)
        if (result.code == 200) {
          returnData = successFunction(result);
        } else {
          alert(result.msg)
        }
      },
      error: function (jqXHR) {
        console.log(jqXHR)
        alert("发生错误:" + jqXHR.status);
      }
    });
  }

但是除了登录等不需要不需要token的接口,调用其它的接口都一脸懵逼的报找不到token异常,为此,我猜想是跨域配置时,我没有允许Authorization请求头放行。也就是上面这句Java代码配置不对:

	corsConfiguration.addAllowedHeader("*");

我开始尝试重新配置这个addAllowedHeader:

 corsConfiguration.addAllowedHeader("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
 corsConfiguration.addAllowedHeader("Authorization,*");
 corsConfiguration.addAllowedHeader("*,Authorization");

无一例外,失败了。重新审视一下问题,有没有可能是springsecurity的过滤器链的优先级比这个跨域过滤器的优先级高?
因为前台小弟等着对接,所以没那么多时间去考虑那么多,就采取了一种简单粗暴的形式去解决。来不及去深究真正原因,直接不采用bean的形式去做跨域处理,而采用实现filter的形式,并通过 Integer.MIN_VALUE 指定优先级最高。


import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@Configuration
@Order(Integer.MIN_VALUE)
@Slf4j
public class CustomCorsFilter implements Filter {

   @Override
   public void destroy() {

   }

   @Override
   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
           throws IOException, ServletException {

       HttpServletRequest request = (HttpServletRequest) req;
       HttpServletResponse response = (HttpServletResponse) res;
       log.info("Authorization={}",request.getHeader("Authorization"));
       Enumeration<String> es = request.getHeaderNames();
       String s = "";
       while (es.hasMoreElements()){
           s = es.nextElement()+","+s;
       }
       log.info(s);
       response.setHeader("Access-Control-Allow-Origin", "*");
       response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");
       response.setHeader("Access-Control-Max-Age", "3600");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
       chain.doFilter(req, res);

   }

   @Override
   public void init(FilterConfig arg0) throws ServletException {

   }

}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 前后端分离是一种将前端界面与后端逻辑进行分离开发的架构方式,使得前端与后端可以并行开发。OAuth 2.0是一种授权框架,用于授权和认证流程的规范化,而Spring Security是一个在Java中实现安全控制的框架,提供了大量的安全特性。Spring Authorization Server是Spring Security中用于实现授权服务器的模块,它支持OAuth 2.0的各种授权模式。 密码模式是OAuth 2.0中的一种授权模式,它允许用户通过提交用户名和密码来获取访问令牌,然后使用该令牌来访问受保护的资源。在前后端分离的架构中,可以使用Spring Security配合Spring Authorization Server来实现密码模式的认证和授权。 在密码模式下,前端首先需要收集用户的用户名和密码,并将其发送给后端。后端使用Spring Security提供的密码编码器对密码进行加密,并验证用户名和密码的正确性。如果验证通过,则后端向客户端颁发一个访问令牌,通常是一个JWT(JSON Web Token)。前端使用获得的访问令牌来访问需要受保护的资源,每次请求将该令牌作为Authorization头的Bearer字段发送给后端进行验证。后端可以使用Spring Security的资源服务器来验证该令牌的有效性,并根据用户的权限控制对资源的访问。 使用Spring Security和Spring Authorization Server的密码模式可以实现安全的前后端分离架构。通过合理配置和使用安全特性,可以保障用户的身份认证和资源的授权,确保系统的安全性。 ### 回答2: 前后端分离是一种软件架构模式,前端和后端通过使用API进行通信,分别负责处理用户界面和数据逻辑。OAuth 2.0是一种用于授权的开放标准协议,它允许用户在第三方应用程序中授权访问其受保护的资源。Spring Security是Spring框架中的一个模块,提供了身份验证和授权功能。 在前后端分离的架构中,前端应用程序通常需要使用OAuth 2.0协议进行用户授权,以访问后端应用程序的受保护资源。为了实现密码模式,我们可以使用Spring Security的模块之一,即spring-authorization-server。 spring-authorization-server是Spring Security的一个子模块,用于实现OAuth 2.0协议中的授权服务器。密码模式是OAuth 2.0协议中的一种授权模式,允许前端应用程序通过用户的用户名和密码进行授权。密码模式在安全性上有一定的风险,因此在实际应用中需要谨慎使用。 使用spring-authorization-server的密码模式,我们可以在前端应用程序中收集用户的用户名和密码,并将其提交给后端应用程序进行验证。后端应用程序将使用Spring Security进行身份验证,并向前端应用程序颁发一个访问令牌,该令牌可以用于后续的API请求。 通过使用前后端分离、OAuth 2.0和spring-authorization-server的密码模式,我们可以实现安全的用户授权和身份验证机制,确保只有经过授权的用户才能访问受保护的资源。这种架构模式能够提高系统的安全性和可扩展性,适用于各种类型的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的孤独与美酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值