Spring Cloud Gateway 整合OAuth2.0 实现统一认证授权
https://blog.csdn.net/Pastxu/article/details/124538383

GateWay——向其他服务传递参数数据
https://blog.csdn.net/qq_38322527/article/details/126530849

需求

随着微服务越来越多,把鉴权操作统一放到网关去做,如果微服务自己有额外的鉴权处理,可以在自己的微服务中处理。

1、在网关层完成url层面的鉴权操作。
所有的OPTION请求都放行。
所有不存在请求,直接都拒绝访问。
user-provider服务的findAllUsers需要 user.userInfo权限才可以访问。

2、将解析后的jwt token当做请求头传递到下游服务中。
3、整合Spring Security Oauth2 Resource Server

四个角色

客户端:需要访问微服务资源
网关:负责转发、认证、鉴权
OAuth2.0授权服务:负责认证授权颁发令牌
微服务集合:提供资源的一系列服务。

流程说明

授权服务器作为独立服务提供,用户登录请求通过网关转发到授权服务器。

认证和授权步骤,简单来说就是客户端根据约定的ClientID、ClientSecret、Scope来从Access Token URL地址获取AccessToken,并经过AuthURL认证,用得到的AccessToken来访问其他资源接口。

网关除负载转发请求外,还提供令牌(身份)认证和鉴权服务。当客户端访问资源时,请求先达到网关,网关检查携带的令牌是否合法和有效以及判断是否有权限访问资源后,再进行请求转发。

认证服务配置 @EnableAuthorizationServer

新建 AuthorizationServerConfig.java

在这里插入图片描述

UserDetailsServiceImpl

从数据库获取用户信息。
在这里插入图片描述

身份验证提供者 DaoAuthenticationProvider

JwtAuthenticationProvider extends DaoAuthenticationProvider
在这里插入图片描述

Gateway 网关服务

网关服务作为Oauth2的资源服务、客户端服务使用,对访问微服务的请求进行统一的校验认证和鉴权操作。

需要配置的内容如下:
认证过滤器,其中利用了认证管理器对令牌的校验。
鉴权管理器、令牌失效异常处理、无权限访问异常处理。
白名单配置。
跨域过滤器的配置。

在pom.xml中添加相关依赖,主要是Gateway、Oauth2和JWT相关依赖;
https://blog.51cto.com/u_13626762/5227256

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-resource-server</artifactId>
        </dependency>

JWT令牌服务配置

使用JWT令牌,配置要和认证服务的令牌配置相同。
在这里插入图片描述

认证管理器配置

认证管理的作用就是获取传递过来的令牌,对其进行解析、验签、过期时间判定。
新建JwtAuthenticationManager,实现ReactiveAuthenticationManager接口。
在这里插入图片描述

鉴权管理器自定义

经过认证管理器认证成功后,就需要对令牌进行鉴权,如果该令牌无访问资源的权限,则不允通过。
新建JwtAccessManager,实现ReactiveAuthorizationManager
![![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6e604278c501437fbeda5abd9c7c8763.png](https://img-blog.csdnimg.cn/direct/39307d09de2f4617935a5a0e547fdb49.pn

全局异常

返回自定义的异常信息。

令牌无效或者过期时定制结果

如果令牌失效或者过期,则会直接返回,这里需要定制提示信息。
新建RequestAuthenticationEntryPoint,实现ServerAuthenticationEntryPoint

无权限时的定制结果

鉴权的过程中,如果无该权限,也是会直接返回,这里也需要定制提示信息。
新建RequestAccessDeniedHandler,实现ServerAccessDeniedHandler

@EnableWebFluxSecurity

OAuth2相关组件已经准备就绪,现在直接配置到OAuth2中。
新建WebFluxSecurityConfig配置类,标注注解 @EnableWebFluxSecurity

@Configuration
@EnableWebFluxSecurity
public class WebFluxSecurityConfig {
    @Resource
    private JwtAuthenticationManager jwtAuthenticationManager; //token管理器
    @Resource
    private JwtAccessManager jwtAccessManager;
    //private final IgnoreUrlsConfig ignoreUrlsConfig; //白名单配置

    //认证服务器 配置用户认证
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        log.info("init WebFluxSecurity SecurityWebFilterChain");
        //
        //通过认证管理器进行令牌校验
        //
        //认证过滤器
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(jwtAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        return http
                .httpBasic().disable()
                .csrf().disable()
                .authorizeExchange()
                //鉴权... 略
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                .anyExchange().access(jwtAccessManager)
                .and()
                //token认证过滤器
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                .build();
    }
}

GlobalFilter 配置全局过滤器

网关认证鉴权成功后,下游微服务获取到当前用户的详细信息。
在这里插入图片描述

在这里插入图片描述

订单微服务搭建

由于在网关层面已经做了鉴权了(细化到每个URI),因此微服务就不用集成Spring Security单独做权限控制了。

新建一个过滤器AuthenticationFilter,用于解密网关传递的用户数据

@Component
public class AuthenticationFilter extends OncePerRequestFilter {
    //
}

新建两个接口,返回当前登录的用户信息

@RestController
@RequestMapping("/order")
public class UserController {

    @RequestMapping("/login/info")
    public String info() { return OauthUtils.getCurrentUser(); }

    @RequestMapping("/login/admin")
    public String admin(){ return OauthUtils.getCurrentUser(); }

}

测试

同时启动三个服务

问题

使用TokenEnhancer 导致 access_token不是jwt格式了

实现TokenEnhancer,自定义token导致access_token不是jwt格式。

AccessTokenConverter 作用是把token字符串转换成OAuth2AccessToken对象。
TokenEnhancer作用是在OAuth2AccessToken 里添加额外的信息。
JwtAccessTokenConverter 即实现了AccessTokenConverter接口,也实现了TokenEnhancer接口。
链接:https://blog.csdn.net/qq_19636353/article/details/126987926

{
	"access_token": "d2b97ea9-4cea-4f8b-9832-228bbd6ba985",
	"token_type": "bearer",
	"refresh_token": "b557e569-1b9e-46e8-af39-725c38f482a5",
	"expires_in": 3599,
	"scope": "all",
	"user_id": "101"
}

设置tokenServices()

使用JWT替换Token 及 JWT内容增强
https://blog.csdn.net/qq_43692950/article/details/122525414

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

参考资料

Spring gateway + Oauth2 https://www.cnblogs.com/FullStackProgrammer/p/15607416.html
Spring Cloud Gateway+Oauth2实现统一认证和鉴权 https://zhuanlan.zhihu.com/p/287814029
使用JWT替换Token 及 JWT内容增强 https://blog.csdn.net/qq_43692950/article/details/122525414
分布式认证授权-授权码存储到数据库 https://blog.csdn.net/u011066470/article/details/120047360
gateway-统一权限-认证 RBAC https://blog.csdn.net/JAVAMysql111/article/details/124069500

SpringCloud + Gateway + Security 搭建微服务统一认证授权(附源码)https://blog.51cto.com/u_15191078/5359675
Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作 https://www.shuzhiduo.com/A/E35p0bEy5v/#1jar_28
Spring Cloud Gateway + JWT 实现统一的认证授权 https://blog.51cto.com/u_15973676/6074600?articleABtest=0

========================================================================================

WebFlux Spring Security配置 https://www.cnblogs.com/tangyouwei/p/10032668.html
Security 与响应式 WebFlux https://ld246.com/article/1599217666900

Spring Security系列(三)——WebFlux配置方式以及多登陆入口实现
https://blog.51cto.com/u_15477117/4905933
权限认证过滤器 示例中,简单的打印了一下token,并未将token转换为AuthenticationToken对象。
Logo

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

更多推荐