Implementing Microservice-Level Authorization with Custom Annotations in Spring Cloud Alibaba
This article explains how to shift authentication and authorization from the gateway to downstream microservices in a Spring Cloud Alibaba environment by removing the gateway's ReactiveAuthorizationManager, creating three custom annotations (@RequiresLogin, @RequiresPermissions, @RequiresRoles), defining an AOP aspect to enforce them, and demonstrating their usage with Feign calls.
The author first recalls previous articles that integrated Spring Security with Spring Cloud Gateway for unified authentication and authorization, then introduces the alternative approach of delegating authorization to each downstream microservice while keeping the gateway solely for routing.
To achieve this, the gateway's ReactiveAuthorizationManager is disabled by permitting all requests in the route configuration, as shown in the code snippet:
http
....
// whitelist directly permit
.pathMatchers(ArrayUtil.toArray(whiteUrls.getUrls(), String.class)).permitAll()
// all other requests also permit
.anyExchange().permitAll()
.....Next, three custom annotations are defined to replace Spring Security's built‑in ones:
/**
* @author 公众号:码猿技术专栏
* @url: www.java-family.cn
* @description 登录认证的注解,标注在controller方法上,一定要是登录才能的访问的接口
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequiresLogin {} /**
* @author 公众号:码猿技术专栏
* @url: www.java-family.cn
* @description 标注在controller方法上,确保拥有指定权限才能访问该接口
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequiresPermissions {
String[] value() default {};
Logical logical() default Logical.AND;
} /**
* @author 公众号:码猿技术专栏
* @url: www.java-family.cn
* @description 标注在controller方法上,确保拥有指定的角色才能访问该接口
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequiresRoles {
String[] value() default {OAuthConstant.ROLE_ROOT_CODE, OAuthConstant.ROLE_ADMIN_CODE};
Logical logical() default Logical.AND;
}An AOP aspect PreAuthorizeAspect intercepts any method annotated with these custom annotations. The aspect extracts the method, checks for each annotation, and invokes helper methods ( doCheckLogin , doCheckRole , doCheckPermissions ) to validate the current user's token, roles, and permissions.
@Aspect
@Component
public class PreAuthorizeAspect {
public static final String POINTCUT_SIGN = " @annotation(com.mugu.blog.common.annotation.RequiresLogin) || @annotation(com.mugu.blog.common.annotation.RequiresPermissions) || @annotation(com.mugu.blog.common.annotation.RequiresRoles)";
@Pointcut(POINTCUT_SIGN)
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
checkMethodAnnotation(signature.getMethod());
return joinPoint.proceed();
}
public void checkMethodAnnotation(Method method) {
if (method.getAnnotation(RequiresLogin.class) != null) { doCheckLogin(); }
if (method.getAnnotation(RequiresRoles.class) != null) { doCheckRole(method.getAnnotation(RequiresRoles.class)); }
if (method.getAnnotation(RequiresPermissions.class) != null) { doCheckPermissions(method.getAnnotation(RequiresPermissions.class)); }
}
private void doCheckLogin() { /* validate login token */ }
private void doCheckRole(RequiresRoles requiresRoles) { /* compare token roles with annotation roles */ }
private void doCheckPermissions(RequiresPermissions requiresPermissions) { /* business‑specific permission check */ }
}Usage examples show how to protect controller endpoints. For instance, only users with the admin or root role can add an article:
@RequiresRoles
@AvoidRepeatableCommit
@ApiOperation("添加文章")
@PostMapping("/add")
public ResultMsg
add(@RequestBody @Valid ArticleAddReq req) {
// ...
}The article also warns that applying @RequiresRoles to Feign‑client‑backed endpoints will cause the Feign call to fail because the role check is performed on the downstream service as well.
In conclusion, delegating authorization to microservices can simplify certain scenarios, but the author recommends keeping authentication centralized at the gateway unless specific business requirements dictate otherwise.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.