微服务调用时,开放某个接口设置不需要oauth2 认证即可访问

目标
  • 是把不需要认证的接口给资源服务permitAll
思路
  • 创建一个自定义的注解
  • 把所有带注解的URL给资源服务permitAll
1、创建不鉴权注解@AuthIgnore
/**
 * @author czx
 * @title: AuthIgnore
 * @projectName ms
 * @description: TODO 忽略token 直接开放api
 * @date 2019/7/24 19:21
 */
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthIgnore {

}
2、在服务启动时把有@AuthIgnore 注解的接口保存到一个集合

/**
 * @Description //TODO $忽略认证URL配置
 * @Date  2019/7/24 19:26
 * @Author czx
 **/
@Configurable
@ConfigurationProperties(prefix = "security.oauth2.client.ignore-urls")
public class AuthIgnoreConfig implements InitializingBean {

    @Autowired
    private WebApplicationContext applicationContext;

    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
    private static final String ASTERISK = "*";

    @Getter
    @Setter
    private List<String> ignoreUrls = new ArrayList<>();

    @Override
    public void afterPropertiesSet() throws Exception {
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        map.keySet().forEach(mappingInfo -> {
            HandlerMethod handlerMethod = map.get(mappingInfo);
            AuthIgnore method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), AuthIgnore.class);
            Optional.ofNullable(method)
                    .ifPresent(authIgnore -> mappingInfo
                            .getPatternsCondition()
                            .getPatterns()
                            .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, ASTERISK))));
            AuthIgnore controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), AuthIgnore.class);
            Optional.ofNullable(controller)
                    .ifPresent(authIgnore -> mappingInfo
                            .getPatternsCondition()
                            .getPatterns()
                            .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, ASTERISK))));
        });
    }
}
3、把@AuthIgnore集合给资源服务器设置为忽略验证
/**
 * @Author czx
 * @Description //TODO 资源服务器配置
 * @Date 17:03 2019/4/3
 **/
@Slf4j
@AllArgsConstructor
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    private final AuthIgnoreConfig authIgnoreConfig;
    
    代码忽略.....
    
    /**
     * @Description //TODO http 请求的一些过滤配置
     **/
    @Override
    public void configure(HttpSecurity http) throws Exception {
        String[] urls = authIgnoreConfig.getIgnoreUrls().stream().distinct().toArray(String[]::new);
        http
            .headers().frameOptions().disable()
            .and()
            .authorizeRequests().antMatchers(urls).permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable();
    }
    
    代码忽略.....
}
最后

服务启动后自动加载所有的@AuthIgnore标注的URL给资源服务设置为忽略认证

具体代码:传送门 : https://github.com/yzcheng90/ms

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐