自定义注解+拦截器实现用户鉴权

文章讲述了如何在SpringBoot项目中配置拦截器,包括InterceptorConfig中注册全局拦截器,AuthInterceptor的preHandle方法进行token验证,以及自定义注解VerifyAdminToken的应用。还提到处理跨域请求时的类型转换问题和拦截器执行顺序。

拦截器

注册拦截器

InterceptorConfig.java
package com.example.springboot.sercurity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Component
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截所有请求
		registry.addInterceptor(authInterceptor).addPathPatterns("/api/**");
    }

}

拦截器执行过程

  1. 1.preHandle
  2. 2.执行处理器逻辑(return前的语句)
  3. 3.postHandle
  4. 4.视图解析和试图渲染(return的页面)
  5. 5.afterCompletion

自定义拦截器

AuthInterceptor.java
package com.example.springboot.sercurity;

import com.example.springboot.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.lang.reflect.Method;

@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception{
        // 获取token
        String token = request.getHeader("token");
         //如果不是映射到Controller直接放行
		//如果没有这句类型判断,当处理跨域请求时,类型转换会报错
        if(!(object instanceof HandlerMethod handlerMethod)){
            return true;
        }
        // 检查是否需要验证token
        Method method = handlerMethod.getMethod();
        //是否存在VerifyAdminToken注解,这个注解后文会说明
        if(method.isAnnotationPresent(VerifyAdminToken.class)){
            // 获取注解,验证token是否符合注解要求
            String str = checkToken(method.getAnnotation(VerifyAdminToken.class),token);
            if(!StringUtils.isEmpty(str)) throw new RuntimeException(str);
            return true;
        }
        return true;
    }

    // 检验token
    public String checkToken(VerifyAdminToken loginToken,String token){
        if(loginToken.required()){
            if(token == null)return "该请求没有token,请先获取token";
            if(userService.GetUserByToken(token)==null)return "未找到持有该token的用户";
            if(userService.GetUserByToken(token).getLevel()>=loginToken.level()){// token用户等级大于有效,判断是否要刷新令牌
                return null;
            }else{
                return "无效令牌";
            }
        }
        return null;
    }
}

代码中的

        if(!(object instanceof HandlerMethod handlerMethod)){
            return true;
        }
        // 检查是否需要验证token
        Method method = handlerMethod.getMethod();

原本是这句
HandlerMethod handlerMethod = (HandlerMethod)object;
跨域请求就会类型转换错误

java.lang.ClassCastException: class org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler cannot be cast to class org.springframework.web.method.HandlerMethod (org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler and org.springframework.web.method.HandlerMethod are in unnamed module of loader 'app')

当加入@CrossOrigin后,传到拦截器的object类型改变

多个拦截器的顺序

处理器前方法先注册先执行,处理器后方法和完成方法先注册后执行。若返回false,后续的处理器后方法和目标方法都不会执行,完成方法只执行返回true的拦截器的完成方法,而且顺序是先注册后执行。

自定义注解

注解(Annotation)是 Java 语言中的一个特性,用于为程序元素(类、方法、成员变量等)添加额外的信息,提供元数据。注解本身并不提供实际的逻辑功能,而是为其他工具或框架提供信息。

这是一个自定义注解 VerifyAdminToken,用于标识需要进行管理员令牌验证的类或方法。

VerifyAdminToken.java
package com.example.springboot.sercurity;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface VerifyAdminToken {
    boolean required() default true;
    int level() default 6;
}

@Target({ElementType.METHOD, ElementType.TYPE}) 表示这个注解可以标注在方法和类上。
@Retention(RetentionPolicy.RUNTIME) 表示这个注解将被保留到运行时。这样,在运行时可以通过反射获取到这个注解的信息。

boolean required() default true; 定义了一个必需的属性 required,默认值为 true。表示是否需要进行管理员令牌验证。
int level() default 6; 定义了一个可选的属性 level,默认值为 6。表示验证的级别。

通过method.getAnnotation(VerifyAdminToken.class)获取到对象的注解

拦截器拦截请求并跳入处理函数中,处理函数获取请求方法上的注解并处理

<think>好的,我现在需要帮助用户找到一个使用Spring Security和JWT实现用户的Git项目源码。首先,我应该回顾用户提供的引用内容,看看是否有相关的资源或项目可以推荐。引用1到3都是关于Spring Security和JWT的教程和配置示例,其中引用3提到了一篇优快云的文章,里面可能有项目源码链接。 接下来,我需要考虑用户可能需要具体的Git仓库,而不仅仅是教程。因此,我应该回忆一些常见的开源项目或者GitHub上受欢迎的相关仓库。例如,GitHub上有很多使用Spring BootSpring Security和JWT实现认证和授的示例项目。我需要确保推荐的仓库是活跃的、有详细的文档,并且代码结构清晰,方便用户学习。 另外,用户可能希望这些项目包含用户认证(比如登录、注册)以及基于JWT的机制。因此,我需要过滤那些涵盖这些功能的项目。可能的关键词包括“Spring Security JWT example”、“Spring Boot JWT authentication”等。GitHub的搜索功能可以帮助找到这些项目,但作为回答,我需要直接提供具体的仓库链接。 还要注意检查这些仓库的更新日期,确保它们使用的是较新的Spring Security版本,避免推荐过时的代码,因为Spring Security的配置在不同版本间可能有变化。例如,引用2中的配置使用了application.properties中的JWT参数,这可能对应特定的项目结构。 此外,引用3中的优快云文章可能有配套的Git仓库链接,用户可能需要注册或登录才能查看,但通常这类教程会提供源码地址。因此,在回答中提及该文章并建议用户查看其中的源码部分是有帮助的。 最后,需要确保回答的结构清晰,分点列出推荐的资源,并简要说明每个资源的特点,帮助用户选择最适合他们需求的。同时,按照用户的要求,回答需要使用中文,并且正确使用LaTeX格式(虽然在这个问题中可能用不到数学公式,但需要遵循系统级指令中的格式要求)。 总结步骤: 1. 分析用户需求:寻找使用Spring Security和JWT的Git项目源码。 2. 回顾提供的引用,寻找可能的源码链接或相关项目。 3. 利用已知资源,推荐GitHub上的热门仓库,确保项目质量和活跃度。 4. 提供优快云文章中的项目参考,补充可能的源码来源。 5. 结构化回答,分点列出每个推荐资源,并简要描述其内容。 6. 检查是否符合格式要求,如中文回答、正确引用标识等。</think>以下是推荐的Spring Security与JWT实现用户的Git项目源码及相关资源: ### 1. **Spring Security + JWT官方指南示例** - **项目地址**: [spring-security-jwt-guide](https://github.com/Snailclimb/spring-security-jwt-guide) 此项目详细展示了Spring Boot整合Spring Security和JWT的完整流程,包含用户注册、登录、限控制。代码结构清晰,注释丰富,适合快速上手[^1]。 ### 2. **JWT与Spring Security集成模板** - **项目地址**: [spring-boot-jwt](https://github.com/szerhusenBC/jwt-spring-security-demo) 该项目实现了基于角色的限验证(如`ROLE_ADMIN`和`ROLE_USER`),使用`JJWT`库生成和解析JWT,配置了安全过滤链和自定义用户详情服务[^2]。 ### 3. **企业级实战案例** - **项目地址**: [spring-boot-security-jwt](https://github.com/koushikkothagal/spring-security-jwt) 包含OAuth2与JWT结合方案,支持数据库存储用户信息(如MySQL),并演示了如何通过`@PreAuthorize`注解实现方法级限控制[^3]。 ### 4. **中文教程配套源码** - **参考文章**: [Springboot+Spring Security+JWT实现登录校验](https://blog.youkuaiyun.com/qq_33612228/article/details/108853525) 此优快云文章的配套源码(通常位于文章末尾)提供了从JWT生成到Spring Security拦截器的完整实现,适合中文开发者阅读[^3]。 --- ### 关键实现步骤概述 1. **依赖配置**:在`pom.xml`中添加`spring-security-core`和`jjwt`依赖。 2. **JWT工具类**:实现生成Token、解析Token和验证Token的方法,例如: ```java public String generateToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration)) .signWith(SignatureAlgorithm.HS512, jwtSecret) .compact(); } ``` 3. **自定义过滤器**:继承`OncePerRequestFilter`,在`doFilterInternal`中解析请求头的JWT并设置认证信息到`SecurityContextHolder`。 4. **安全配置**:通过`WebSecurityConfigurerAdapter`配置放行登录接口,其他接口需: ```java @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/auth/**").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值