Spring Boot+Vue+Spring Security OAuth2的前后端分离项目实现研究

本文介绍了使用Spring Boot+Vue+Spring Security OAuth2实现前后端分离项目时遇到的跨域、OPTIONS 401、PreAuthorize注解无效和Token失效处理等关键问题,并提供了详细的解决方案。涉及到的配置包括跨域Filter、OPTIONS请求配置、自定义Voter以及Token失效后的处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业余在开发一个Spring Boot+Vue+Spring Security OAuth2的一个前后端分离项目,其中遇到不少如跨域、OPTIONS请求处理、PreAuthorize注解无效、Token失效处理等问题,记录如下。

在此项目中,资源服务与授权服务在同一应用中,使用端口8081;前端应用使用端口8080。前端使用axios进行ajax调用。
关于Spring Security OAuth2相关内容,可参考:http://liumoran.cn/topic/detail?id=1

1. 后端处理跨域请求问题

如果前后端部署在不同应用服务器上,后端需要配置跨域访问才成。如未配置跨域访问,浏览器F12打开高度页面的Console界面中,可以看到以下信息:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/getLoginUser. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

Spring Boot中配置跨域请求,可以通过定义Filter的方式实现:

@Component
public class MyCorsFilter implements Filter {
   
   
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
   
   
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin","http://localhost:8080");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, Authorization");
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
   
   }

    @Override
    public void destroy() {
   
   }

}

2. OPTIONS报401问题

为什么在正常的请求前要发送OPTIONS请求?

用户登录成功后,当前端往后端发送的请求中包含有Authorization头,并且是跨域请求时,浏览器将会往后端发送对应的OPTIONS请求,以确认后台服务是否支持对受保护资源的跨域访问。

由于OPTIONS请求中并不带有Token,因此请求被Spring Security OAuth2拦截到后,检查发现没有Token,直接返回401给前端页面了。

如何配置?

可以在Spring Security的配置类中配置允许所有OPTIONS请求访问,如下所示:

    @Override
    public void configure(HttpSecurity http) throws Exception {
   
   
        http
                .anonymous()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "**").permitAll()
                .anyRequest().authenticated();
    }

其中省略掉了其它的资源访问授权配置。

但在配置后前端访问仍旧报401!!经过排查,按前面所说,我是在Spring Security的配置类中添加这个配置的,但实际上,资源服务器中对请求是否有权限访问的处理,是在资源服务器的配置中进行的,因此在单独的Spring Security配置类中进行配置并不会生效!必须在继承自ResourceServerConfigurerAdapter的配置类中进行该项配置。

在资源服务中,实际上是不需要单独的Spring Security的配置类的,直接使用ResourceServerConfigurerAdapter即可完成对各类资源的授权配置。此时的配置类如下:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfigurer extends ResourceServerConfigurerAdapter {
   
   
    @Autowired
    private RealAuthenticationProvider authenticationProvider;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
   
   
        resources.resourceId("testResource")
                .stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
   
   
        http
                .authorizeRequests()
                    .antMatchers(HttpMethod.OPTIONS, "**").permitAll()
                    .antMatchers("/*", "/css/**/*", "/js/**/*", "/icons/**/*", "/upload/*",
                            "/h2-console/", "/h2-console/**/*", "/topic/**/*").permitAll()
                    .anyRequest().authenticated()
                .and()
                .formLogin()
                    .lo
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值