解决Spring cloud 整合security,token过期以后跳转默认登录页的问题

解决Spring security token过期以后跳转默认登录页的问题

1、背景

因为启动新项目,用到了spring security的架构。新项目是一个前后端分离的项目,但是整合进来以后,登录没有问题,但是只要401,就会弹出spring security的默认登录页。如下图
在这里插入图片描述

排查过程

试过很多方式,比方:禁用formLogin(),禁用httpBasic都没有用,包括在@SpringBootApplication注解上加(exclude = {SecurityAutoConfiguration.class})也不行。谷歌百度的方法大多都试过了,找不到合适的解决办法。
后来突然想到项目中的security引入是借鉴的码云的一个大佬的项目,就想试试看别人的项目会不会也这样,结果跑起来发现并不会。这样就找到解决的方向了,一定是配置出现了什么问题。所以就在一切在401可能访问到的过滤器上打断点,然后和自己项目对比,终于发现了区别。是自定义继承HttpBasicServerAuthenticationEntryPoint的类有区别
码云大佬地址:https://gitee.com/AloneH/spring-security_springcloud-gateway.git

package com.vdpub.auth.security.webflux.handler;

import com.vdpub.auth.security.webflux.utils.ResponseUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @description: 自定义token验证失败处理逻辑
 *  *                  1、token验证失败的处理逻辑(token为空,或者过期时)
 *  *                  2、设置响应头
 *  *                  3、写入响应内容
 * @author: Max
 * @create: 2021-03-05 17:53
 **/
@Component
public class CustomHttpBasicServerAuthenticationEntryPoint extends HttpBasicServerAuthenticationEntryPoint /* implements ServerAuthenticationEntryPoint */{


    /**新的定义*/
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
    private static final String DEFAULT_REALM = "Realm";
    private static final String WWW_AUTHENTICATE_FORMAT = "Basic %s"; // 区别所在

    
    /**原定义***/
//    private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
//    private static final String DEFAULT_REALM = "Realm";
//    private static String WWW_AUTHENTICATE_FORMAT = "Basic realm=\"%s\""; // 区别所在
    
    private final String headerValue = createHeaderValue(DEFAULT_REALM);
    public CustomHttpBasicServerAuthenticationEntryPoint() {
    }

    /**
     * 创建错误响应头中的Authenticate
     * @param realm
     * @return
     */
    private static String createHeaderValue(String realm) {
        Assert.notNull(realm, "realm cannot be null");
        return String.format(WWW_AUTHENTICATE_FORMAT, realm);
    }


    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) {
        ServerHttpResponse response = exchange.getResponse();
        // 设置响应头
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().set(WWW_AUTHENTICATE, this.headerValue);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 三设置 验证异常返回信息
        String responseBodyString = ResponseUtil.getResponse(e.getMessage(), HttpStatus.UNAUTHORIZED);
        byte[] responseBodyBytes = responseBodyString.getBytes();
        // 写入信息
        return response.writeWith(Mono.just(response.bufferFactory().wrap(responseBodyBytes)));
    }
}

解决办法

既然发现了是这里的区别,就直接进行了替换,将上述贴的代码中注释中的原定义内容换成新定义的内容即可。
主要是请求头的问题,换完以后,请求头由图一变为图二
图一:
在这里插入图片描述
图二:
在这里插入图片描述

至此问题解决,欢迎大家有问题一起讨论。不对地方也请大家指出、
转载请注明出处

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于Spring Cloud整合Spring SecurityToken认证,你可以按照以下步骤进行操作: 1. 首先,确保你已经配置好了Spring CloudSpring Security依赖。 2. 创建一个Spring Security的配置类,这个类应该继承自`WebSecurityConfigurerAdapter`,并且覆写`configure(HttpSecurity http)`方法。在这个方法中,你可以配置需要认证和授权的URL路径,例如: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/public/**").permitAll() .anyRequest().authenticated(); } } ``` 3. 创建一个Token生成和验证的服务类。你可以使用Spring Security提供的`Jwt`库来处理Token操作。这个服务类应该有两个核心方法:一个用于生成Token,一个用于验证Token的有效性。 4. 在需要进行认证和授权的接口上添加`@PreAuthorize`注解,指定需要的权限。例如: ``` @RestController @RequestMapping("/api/public") public class PublicController { @GetMapping("/hello") @PreAuthorize("hasAnyRole('ADMIN', 'USER')") public String hello() { return "Hello, world!"; } } ``` 5. 在Spring Cloud的网关中配置Token验证过滤器。你可以使用Spring Cloud Gateway或者Zuul来实现网关功能,并在网关层进行Token验证。 以上是基本的步骤,你可以根据具体的需求进行调整和扩展。希望对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值