2026-10-24 19:35:25
微服务中的鉴权是确保系统安全的核心环节,需结合分布式架构特点设计统一且灵活的机制。以下是具体实现方案:
一、鉴权基础与常见方式核心目标通过认证(Authentication)和授权(Authorization)确保用户身份合法且具备操作权限。
常见鉴权方式
用户名+密码:需加盐哈希存储密码,HTTPS传输。
多因素认证(MFA):结合密码、手机验证码、生物识别等。
OAuth 2.0:适用于第三方应用授权(如社交登录)。
JWT(JSON Web Token):无状态令牌,适合分布式系统,需结合Redis管理状态。
流程:
用户通过网关提交认证信息(如用户名/密码)。
网关转发至认证服务验证,成功则生成JWT并返回客户端。
客户端后续请求携带JWT,服务端通过Redis校验有效性。
图:微服务架构中的认证服务与网关协作流程
外部请求:通过API网关进入,需严格鉴权。
内部请求:微服务间调用,默认信任但需防止外部伪造。
用户登录时,认证服务生成JWT并存储至Redis(键为JWT字符串,值为用户信息,设置过期时间)。
客户端请求携带JWT,服务端先查Redis验证存在性,再解析JWT内容。
Redis过期机制自动清理无效令牌,避免手动管理。
图:JWT生成、存储与校验流程
2. 授权实现(AOP+自定义注解)外部请求授权:
拦截器:在网关或公共包中定义请求头拦截器,提取JWT中的用户权限信息。
AOP切面:通过自定义注解(如@PreAuthorize)标注需要权限校验的方法,拦截请求并比对权限。
示例:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface PreAuthorize { String value(); // 权限表达式,如"hasRole('ADMIN')"}@Aspect@Componentpublic class AuthorizationAspect { @Around("@annotation(preAuthorize)") public Object checkPermission(ProceedingJoinPoint point, PreAuthorize preAuthorize) throws Throwable { String permission = preAuthorize.value(); if (!hasPermission(permission)) { throw new AccessDeniedException("无权限访问"); } return point.proceed(); }}内部请求授权:
自定义注解:标记内部方法(如@InnerAuth),通过AOP检查请求头中的内部标识(如X-Internal-Source: true)。
OpenFeign集成:实现RequestInterceptor,为内部调用自动添加标识头,防止外部伪造。
示例:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface InnerAuth { boolean isUser() default false; // 是否校验用户信息}@Aspect@Componentpublic class InnerAuthAspect { @Around("@annotation(innerAuth)") public Object innerCheck(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable { HttpServletRequest request = ServletUtils.getRequest(); String source = request.getHeader("X-Internal-Source"); if (!"true".equals(source)) { throw new SecurityException("非法内部调用"); } // 用户信息校验(可选) if (innerAuth.isUser()) { String userId = request.getHeader("X-User-Id"); if (StringUtils.isEmpty(userId)) { throw new SecurityException("缺失用户信息"); } } return point.proceed(); }}图:外部请求授权校验流程
四、关键注意事项性能优化
Redis校验JWT存在性时,使用EXISTS命令而非GET,减少数据传输。
对高频接口的权限校验结果进行本地缓存(如Caffeine),减少AOP切面开销。
安全性增强
JWT签名使用强算法(如RS256),避免HS256密钥泄露风险。
内部请求标识头使用动态令牌(如每次请求生成唯一ID),防止重放攻击。
容错设计
Redis故障时,可降级为仅解析JWT(不校验存在性),但需记录日志并报警。
网关需具备熔断机制,防止鉴权服务不可用导致整个系统瘫痪。
微服务鉴权需兼顾统一性(集中认证)与灵活性(分布式授权),通过JWT+Redis实现无状态认证,结合AOP和自定义注解完成细粒度授权控制。内部调用通过标识头隔离,确保安全边界清晰。实际落地时需根据业务需求调整权限模型(如RBAC、ABAC),并持续优化性能与安全性。