spring cloud 集成 oauth2 搭建资源服务器

605 阅读2分钟

今天本来想靠脸吃饭的,呃呃呃呃....我中午没吃

image.png

今天我们来一起探讨一下spring cloud 如何集成 oauth2 搭建服务器

搭建资源服务器

  • 导入maven 依赖
<!--security oauth2安全依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
  • 编写 ResourceServerConfig 实现 ResourceServerConfigurer
  • 配置token存储策略
  • 配置鉴权规则
  • 在启动类加上@EnableGlobalMethodSecurity(prePostEnabled=true)注解开启注解方式鉴权
public class ResourceServerConfig implements ResourceServerConfigurer {

    @Resource
    private PermitAllPorperties permitAllPorperties;

    @Resource
    private TokenStore tokenStore;




    /**
     * 注入token存取策略
     * 开启无状态模式
     * 注入token存取策略,我这里使用的JWT所以不需要调用/oauth/check_token,所以不需要配置RemoteTokenService
     * @param resource
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resource) throws Exception {
        resource.tokenStore(tokenStore)
                .authenticationEntryPoint(new LwAuthenticationEntryPoint())//自定义认证异常处理
                .accessDeniedHandler(new LwAccessDeniedHandler())//自定义权限异常处理
                .stateless(true);
    }


    /**
     * 配置拦截规则
     * 1、客户端作用域必须是server
     * 2、关闭csrf
     * 3、将session设置成无状态模式
     *  permitAllPorperties是我自定义配置类在,他会收集所有带有@IgnoreToken注解方法以及类,放入到IgnoreUrls集合中
     *  通过IgnoreUrls在启动时动态配置不需要鉴权的接口
     * @param httpSecurity
     */
    @Override
    public void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .antMatchers(permitAllPorperties.getIgnoreUrls().stream().toArray(String[]::new)).permitAll()
                .antMatchers("/**").access("#oauth2.hasScope('server')")
                .and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }
    /**
    * 存储策略
    */
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }


    /**
    * JWT转换器
    */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        DefaultAccessTokenConverter defaultConverter = new DefaultAccessTokenConverter();
        defaultConverter.setUserTokenConverter(lwUserAuthenticationConverter());

        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(defaultConverter);
        converter.setSigningKey("123456");
        return converter;
    }
}
@Slf4j
@Configuration
public class PermitAllPorperties implements InitializingBean {

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

    @Resource
    private ApplicationContext applicationContext;

    //需要忽略鉴权的路径集合
    @Getter
    @Setter
    private List<String> ignoreUrls = new ArrayList<>();


    /**
     * 收集所有携带@IgnoreToken的方法以及类
     * 1、将带有@IgnoreToken注解的方法加入到ignoreUrls集合中,需要将@Pathvariable替换成*
     * 2、将带有@IgnoreToken注解的类下所有方法加入到ignoreUrls集合中,需要将@Pathvariable参数替换成*
     *
     * @param
     */
    @Override
    public void afterPropertiesSet() throws Exception {
       //通过RequestMappingHandlerMapping可以拿到所有方法以及类的信息
        RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();

    
        handlerMethods.forEach((info, method) -> {
        //将所有带有IgnoreToken注解的方法请求路径放入到ignoreUrls集合中
            IgnoreToken ignoreToken = AnnotationUtil.getAnnotation(method.getMethod(), IgnoreToken.class);
            Optional.ofNullable(ignoreToken).ifPresent(ignoreToken1 -> info.getPatternsCondition().getPatterns().forEach(url -> {
                ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"));
            }));

            //将所有带有IgnoreToken注解的类路径放入到ignoreUrls集合中
            IgnoreToken controller = AnnotationUtil.getAnnotation(method.getBeanType(), IgnoreToken.class);
            Optional.ofNullable(controller).ifPresent(ignoreToken1 -> info.getPatternsCondition().getPatterns().forEach(url -> {
                ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"));
            }));
        });
    }


}
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
@EnableGlobalMethodSecurity(prePostEnabled=true)  //开始注解方式验证权限
@MapperScan("com.lw.sys.mapper")
public class SysApplication {

    public static void main(String[] args) {
        SpringApplication.run(SysApplication.class, args);
    }
}