spring cloud gateway整合OAuth2实现自定义鉴权

1、OAuth2里面有很多个TokenStore的实现,例如RedisTokenStore,JdbcTokenStore等等,本文以RedisTokenStore实现。

2、自定义CustomAuthorizationManager类实现ReactiveAuthorizationManager接口,重写check()方法

3、关键代码如下

@Component
@Slf4j
public class CustomAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * Determines if access is granted for a specific authentication and object.
     *
     * @param authenticationMono the Authentication to check
     * @param object             the object to check
     * @return an decision or empty Mono if no decision could be made.
     */
    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authenticationMono, AuthorizationContext object) {
        ServerWebExchange exchange = object.getExchange();
        String requestPath = exchange.getRequest().getURI().getPath();
        log.debug("当前请求路径:{}", requestPath);

        PathMatcher pathMatcher = new AntPathMatcher();
        //校验当前请求的url是否在白名单内
        Set<String> whiteUrlList = redisTemplate.opsForSet().members(RedisConstant.WHITE_URL_LIST);
        if (CollectionUtil.isNotEmpty(whiteUrlList)){
            for (String whiteUrl : whiteUrlList) {
                if (pathMatcher.match(whiteUrl, requestPath)) {
                    //将请求头的token移除,避免授权服务校验token
                    ServerHttpRequest request = exchange.getRequest().mutate()
                            .headers(httpHeaders -> httpHeaders.remove("Authorization")).build();
                    log.debug("url: {}, path: {},白名单地址直接放行,并将当前的请求头的token移除",whiteUrl,requestPath);
                    exchange.mutate().request(request).build();
                    return Mono.just(new AuthorizationDecision(true));
                }
            }
        }

        RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
        String authorizationToken = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        log.debug("当前请求头Authorization中的值:{}",authorizationToken);
        if (StringUtils.isBlank(authorizationToken)) {
            log.warn("当前请求头Authorization中的值不存在");
            return Mono.just(new AuthorizationDecision(false));
        }

        String token = authorizationToken.replace(OAuth2AccessToken.BEARER_TYPE + " ", "");
        OAuth2Authentication oAuth2Authentication = redisTokenStore.readAuthentication(token);
        log.debug("当前token所拥有的OAuth2Authentication:{}", oAuth2Authentication);
        Collection<GrantedAuthority> authorities = oAuth2Authentication.getAuthorities();
        log.debug("当前token所拥有的权限:{}",authorities.toString());

        for (GrantedAuthority authority : authorities) {
            String authorityStr= authority.getAuthority();
            if (pathMatcher.match(authorityStr, requestPath)) {
                //设置请求头参数username
                ServerHttpRequest request = exchange.getRequest().mutate()
                        .headers(httpHeaders -> httpHeaders.add("username",oAuth2Authentication.getName())).build();
                exchange.mutate().request(request).build();
                return Mono.just(new AuthorizationDecision(true));
            }
        }
        return Mono.just(new AuthorizationDecision(false));
    }

}

4、主要思路是:

a.获取当前访问路径,当前访问路径是否在配置的url白名单里面,若是则将当前请求的请求头“Authorization”移除,避免授权服务继续校验token,反之则执行以下校验

b、获取当前请求的token值,不存在则校验失败

c、通过redisTokenStore的readAuthentication方法获取当前token所拥有的权限

d、当前token拥有的权限与当前访问地址比对,比对结果则为校验结果

### 回答1: Spring Cloud Gateway可以通过整合OAuth2来实现安全认证和授权功能。具体步骤如下: 1. 引入Spring Security和Spring Security OAuth2依赖。 2. 配置Spring Security和OAuth2的相关配置,包括认证服务器地址、客户端ID和密钥等。 3. 在Spring Cloud Gateway中配置路由规则,并添加安全过滤器,将请求转发到认证服务器进行认证和授权。 4. 在路由规则中添加需要进行安全认证和授权的路径和方法。 5. 在授权成功后,将令牌添加到请求头中,以便后续服务可以获取到令牌信息。 通过以上步骤,就可以实现Spring Cloud Gateway的安全认证和授权功能。 ### 回答2: Spring Cloud Gateway是一个轻量级的API网关,而OAuth2是一种基于授权的安全协议,使用Spring Cloud Gateway整合OAuth2可以为API提供更安全的保护。 首先,我们需要在应用程序中引入OAuth2依赖,如下所示: ``` <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.3.5.RELEASE</version> </dependency> ``` 接下来,我们需要配置OAuth2具体的认证授权过程。在application.yml文件中进行配置,如下所示: ``` spring: security: oauth2: client: registration: client1: client-id: client1 client-secret: secret1 scope: read,write client-authentication-method: post authorization-grant-type: authorization_code redirect-uri: http://localhost:8081/oauth2/callback client-name: Client 1 provider: provider1 ``` 上述配置中,我们设置了客户端ID、秘钥、范围、客户端认证方式、授权类型等必要参数。其中,“authorization_code”是OAuth2的一种授权类型,通过授权码来获取令牌,这是最常用的一种授权类型。 此外,我们还需要在Gateway中进行相关的配置,包括路由规则、认证过滤器、访问权限控制等。具体实现可以参考springcloudgateway的官方文档。 总的来说,使用Spring Cloud Gateway整合OAuth2可以为API提供更安全的保护,同时也为开发人员提供了更多的灵活性和高效性。 ### 回答3: Spring Cloud GatewaySpring Cloud的一个新项目,它基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术,提供了一种构建API网关的方式。OAuth2是一种基于标准的授权协议,允许客户端(包括第三方应用程序和用户代理)访问受保护的资源。那么,如何在Spring Cloud Gateway中集成OAuth2呢? 首先,我们需要在Spring Cloud Gateway中引入spring-cloud-starter-oauth2依赖。然后,在application.yml配置文件中添加以下配置: ``` spring: security: oauth2: client: registration: custom-client: provider: custom-provider clientId: custom-client-id clientSecret: custom-client-secret authorizationGrantType: authorization_code redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" scope: - read - write provider: custom-provider: authorizationUri: https://custom-provider.com/oauth2/authorize tokenUri: https://custom-provider.com/oauth2/token userInfoUri: https://custom-provider.com/oauth2/userinfo userNameAttribute: sub ``` 上面的配置中,我们定义了一个名为custom-client的客户端,该客户端使用了我们自定义OAuth2提供程序custom-provider。在这里,我们还定义了客户端ID和客户端密码,以及授权类型和重定向URI。此外,我们还定义了客户端的作用域和OAuth2提供程序的授权URI、令牌URI和用户信息URI。 在配置完成后,我们需要为Spring Cloud Gateway定义一个OAuth2路由过滤器。可以使用spring-security-oauth2-autoconfigure自动配置这个过滤器。在application.yml中添加以下配置: ``` spring: cloud: gateway: default-filters: - OAuth2GatewayFilterFactory ``` 注意,OAuth2GatewayFilterFactory是spring-security-oauth2-autoconfigure自动配置的名称。 现在,我们可以在Spring Cloud Gateway的路由定义中使用OAuth2路由过滤器了。例如: ``` spring: cloud: gateway: routes: - id: resource-service uri: http://localhost:8080 predicates: - Path=/resource/** filters: - OAuth2=custom-client ``` 在上面的路由定义中,我们使用了自定义OAuth2客户端custom-client。这将强制执行OAuth2认证,以确保只有已验证用户才能访问资源。 最后,我们需要创建一个OAuth2登录页面。使用spring-security-oauth2-autoconfigure依赖可以自动创建登录页面。在application.yml中添加以下配置: ``` spring: security: oauth2: client: registration: custom-client: clientName: Custom Client ``` 上面的配置中,我们定义了客户端的名称为Custom Client。当用户尝试访问受保护的资源时,系统将调用OAuth2登录页面并要求它输入凭据。 这就是在Spring Cloud Gateway中集成OAuth2的过程。通过使用Spring Cloud GatewayOAuth2,我们可以轻松地构建和保护API网关,实现更好的安全性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值