一、oauth2认证中心:登录用户进行认证,生成token, 同时定义受保护的api服务

(一)oauth2的四种认证模式:授权码模式,简化模式,密码模式,客户端模式。其中授权码模式和密码模式用的最多。

A.OAuth2授权码模式: 我们进入一些第三方应用程序时,无需注册,只需要微信授权登录即可,对于我们的服务不需要存储用户的密码,只要存储认证平台返回的唯一ID和用户信息即可,这就是OAuth2常见的授权码模式,它的特点就是:利用第三方权威平台实现用户身份的认证,当然如果我们的公司里面很多微服务,我们自己也可以专门提取出一个认证中心,这个认证中心就是上面说的权威认证平台的角色,所有的微服务均要到这个认证中心做认证,从而实现了单点登录的功能。

B、OAuth2密码模式:通过用户账号和密码的输入,到认证中心获取到token,这个token就是标识用户的身份,一个网站平台或者一个APP,它可能有多个微服务组成,有了这个token后,在一段时间内可以任意访问这些微服务提供的相关api接口服务。

(二)常见的系统架构: 认证中心、微服务、客户端(app/web程序等终端)

客户端:通常就是指应用程序,可能是web或者手机app。

认证中心:OAuth2做账号认证生成token,这个token可以分两种:jwt token放在Header中,或者普通token放在redis中,当然OAuth2还可以当资源鉴权功能。

应用服务:即各个微服务,统一由认证中心做认证与api访问授权。

四、如何开发OAuth2认证中心(即认证服务端)功能:验证账号与密码、生成并存储token、检查token、刷新token等工作。

(1)pom.xml引入spring-cloud-starter-oauth2包,这个包中已经有了spring-cloud-starter-security,所以不需要再单独引入spring-cloud-starter-security。

(2)配置application.yml:主要redis和数据库的配置,OAuth2的一些表需要用到,例如客户端的配置表(oauth_client_details)。

(3)配置spring security:主要配置BCryptPasswordEncoder密码加密工具和忽略oauth2本身的api的拦截的内容。

            很多人这个地方会疑惑为什么OAuth2还需要spring security(主要是这个WebSecurityConfigurerAdapter )

答:这是因为OAuth2本身也同时是一个资源服务(它要对外暴露检查token的接口等),这就需要引入spring security

对授权服务本身的资源(即OAuth2本身的一些api) 进行保护,即OAuth2要开放哪些api。通过spring security(它的WebSecurityConfigurerAdapter )和oauth2的互相配合对不同的url进行访问的控制,通常在WebSecurityConfigurerAdapter 的类中WebSecurity可以配置一些忽略拦截的url的定义。

很多人这个地方还有一个疑惑有了spring security的WebSecurityConfigurerAdapter ,为什么还需要OAuth2的ResourceServerConfigurerAdapter?

              答:WebSecurityConfigurerAdapter主要作用于用户的登录(form login,Basic auth),oauth的一些资源不需要拦截(这个不需要OAuth2保护的url),即设置忽略拦截的url定义,通常就是忽略OAuth2服务自身的一些api 接口的一些定义。

ResourceServerConfigurerAdapter: OAuth2保护一些微服务的资源,这些资源需要token验证后才能访问,主要是对client和token的认证。

ResourceServerConfigurerAdapter优先级高: 如果同时设置了对某一资源的访问控制,会以ResourceServerConfigurerAdapter设置的为准,因为ResourceServerConfigurerAdapter优先级更高,他会优先处理,而WebSecurityConfigurerAdapter会失效

(4) UserDetailsService的代码实现

核心的覆盖重写实现接口中loadUserByUsername方法,这个覆盖实现主要调用系统管理微服务中的用户api服务获取用户,或者验证用户的,一般与数据库的用户账号表密切关联。

(5) 编写AuthServerConfig配置类:

主要实现三个configure方法的重写,各个方法中主要对应以下即

  AuthorizationServerEndpointsConfigurer参数的重写:让它支持password模式,设置用户验证服务,token的redis存储方式等。

       ClientDetailsServiceConfigurer参数的重写:定义各个客户端的约束条件。

public void configure(AuthorizationServerSecurityConfigurer方法的重写:限制客户端对认证接口的访问权限。

/*** 定义授权和令牌端点以及令牌服务*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
{endpoints// 请求方式.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)// 指定token存储位置.tokenStore(tokenStore())// 自定义生成令牌.tokenEnhancer(tokenEnhancer)// 用户账号密码认证.userDetailsService(userDetailsService)// 指定认证管理器.authenticationManager(authenticationManager)// 是否重复使用 refresh_token.reuseRefreshTokens(false)// 自定义异常处理.exceptionTranslator(new CustomWebResponseExceptionTranslator());
}
/*** 配置令牌端点(Token Endpoint)的安全约束*/
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
{oauthServer.allowFormAuthenticationForClients().checkTokenAccess("permitAll()");
}
/*** 配置客户端详情*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
{clients.withClientDetails(clientDetailsService());
}

(6)token可以分来两种: jwt token和redisToken两种方案,根据需要选择,我推荐采用redisToken,jwtToken还需要设置一些配置类,同时配置到认证服务的端点上。

二、spring cloud gateway集成oauth2的支持,实现:网关服务、负责请求转发和鉴权功能

主要工作两块:

1.nacos中对于网关服务配置各个微服务的路由转向:

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        # 认证中心 ,id在全部路由定义中须要惟一,不能重复
        - id: ebyte-auth
          # lb代表从注册中心获取服务,且已负载均衡方式转发
          uri: lb://ebyte-auth
          # 转发规则定义/oauth/**请求都还转发至微服务ebyte-auth
          predicates:
            - Path=/oauth/**
          filters:
            # 自定义验证码处理过滤器
            - ValidateCodeFilter
            # StripPrefix去除掉上面path的第一个前缀,这个前缀更多是前端的api中定义的(前缀加了微服务的名称),和后端的api不符合
            - StripPrefix=1
        # 系统模块
        - id: ebyte-system
          uri: lb://ebyte-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1

2.定义一些过滤器(结合业务实际,例如权限的控制,验证码等)。

3.其它一些相关知识:

在网关集成Oauth2.0后,我们的流程架构如上。主要逻辑如下:
1、客户端应用通过api网关请求认证服务器获取access_token http://localhost:8090/auth-service/oauth/token
2、认证服务器返回access_token

{"access_token": "f938d0c1-9633-460d-acdd-f0693a6b5f4c","token_type": "bearer","refresh_token": "4baea735-3c0d-4dfd-b826-91c6772a0962","expires_in": 43199,"scope": "web"
}

3、客户端携带access_token通过API网关访问后端服务

4、API网关收到access_token后通过 AuthenticationWebFilter 对access_token认证

5、API网关转发后端请求,后端服务请求Oauth2认证服务器获取当前用户

另外:

典型的授权码模式:

  1. 第三方应用向资源持有者请求获取资源
  2. 资源持有者授权给予第三方应用一个许可
  3. 第三方应用将该许可给予认证服务器进行认证,如果认证成功,返回一个Access Token
  4. 第三方应用使用该access token到资源服务器处获取该access token对应的资源(也就是第一步中资源持有者自身的资源)

三、spring cloud gateway集成kaptcha图形验证码(后来我改用了第三包easy-captcha的验证码生成包,更省事效果更佳

步骤1:pom.xml中引入kaptcha包的引用.

步骤2:定义CaptchaConfig配置类,设置kaptcha图形验证码样式以及生成规则(可以配置自定义的文本的生成器KaptchaTextCreator类)

步骤3: 定义ValidateCodeHandler, 即验证码的生成

步骤4:最终的核心就是定义spring cloud gateway的路由配置类RouterFunctionConfiguration,主要把上面的验证码Hander(ValidateCodeHandler)加到路由上来,例如:

/*** 路由配置信息* * @author zhongzk*/
@Configuration
public class RouterFunctionConfiguration
{@Autowiredprivate HystrixFallbackHandler hystrixFallbackHandler;@Autowiredprivate ValidateCodeHandler imageCodeHandler;@SuppressWarnings("rawtypes")@Beanpublic RouterFunction routerFunction(){return RouterFunctions.route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),hystrixFallbackHandler).andRoute(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),imageCodeHandler);}}

步骤5: 前端通过访问url  http://ip:port/code  返回图形验证码,例如在vue中这样定义:

(1)api文件中定义:

// 获取验证码

export function getCodeImg() {return request({url: '/code',method: 'get'})
}

(2)登录页面定义:

<div class="login-code"><img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
methods: {getCode() {getCodeImg().then(res => {this.codeUrl = "data:image/gif;base64," + res.img;this.loginForm.uuid = res.uuid;});},

后端的生成验证码的api定义:

/*** 生成验证码*/
@Override
public AjaxResult createCapcha() throws IOException, CaptchaException
{// 生成验证码String capText = producer.createText();String capStr = capText.substring(0, capText.lastIndexOf("@"));String verifyCode = capText.substring(capText.lastIndexOf("@") + 1);BufferedImage image = producer.createImage(capStr);// 保存验证码信息String uuid = IdUtils.simpleUUID();String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;System.out.println("验证码:" + verifyKey);redisService.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);// 转换流信息写出FastByteArrayOutputStream os = new FastByteArrayOutputStream();try{ImageIO.write(image, "jpg", os);}catch (IOException e){return AjaxResult.error(e.getMessage());}AjaxResult ajax = AjaxResult.success();ajax.put("uuid", uuid);ajax.put("img", Base64.encode(os.toByteArray()));return ajax;
}

回顾:oauth2和 spring cloud alibaba gateway 整合相关推荐

  1. Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos /(非阿里组件))

    Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos)(非阿里组件) 回溯 Gateway 整合 nacos 方式一(复杂/灵活/常用) 方式 ...

  2. Spring Cloud Alibaba gateway ribbon 自定义负载均衡规则。发散灰度发布,金丝雀测试等

    上一篇介绍了,ribbon的组件.本篇要自己写一个灰度方案.其实就是一个很简单的思维扩散. 需求 前端header请求携带version字段.路由服务根据version去需要对应版本的服务集合,进行或 ...

  3. Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也终于发布了最新 ...

  4. 8.Spring Cloud Alibaba教程:整合Seata分布式事务

    概述 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务. 更多的介绍可以参考官方文档:Seata快速入门 本篇主要是介绍Spring Cloud Alibaba ...

  5. Spring Cloud Alibaba基础教程:Sentinel使用Nacos存储规则

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 通过上一篇<使用Sentinel实现接口限流>的介绍,相信大家对Sentinel已经有了初 ...

  6. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 最近管点闲事浪费了不少时间,感谢网友们的留言提醒. 及时纠正路线,继续跟大家一起学习Spring Cl ...

  7. 【Spring Cloud Alibaba】(二)微服务调用组件Feign原理+实战

    系列目录 [Spring Cloud Alibaba](一)微服务介绍 及 Nacos注册中心实战 本文目录 系列目录 前言 什么是RPC? Feign和OpenFeign都是什么? HTTP调用 v ...

  8. Spring Cloud Alibaba 之 RPC 消息:Dubbo 与 Nacos 体系如何协同作业

    上一节我介绍了什么是 OpenFeign 通信组件,讲解了如何基于 OpenFeign 实现微服务间的高可用通信.本文我们将继续探讨微服务通信话题,了解阿里巴巴自家的 RPC 框架 Dubbo 是如何 ...

  9. Spring Cloud Alibaba到底坑不坑?

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 之前我发过一篇<说说我为什么看好Spring Cloud Alibaba>,然后这两天有网 ...

最新文章

  1. libgdx 3D 测试一
  2. API 分页设计与实现探讨
  3. Cocos2d-x 基础元素
  4. 计算机信息工程专业985,信息工程学院
  5. Steger算法(Line_Gauss)-光条中心线提取(基于Hessian矩阵)
  6. ASP.NET 常用语句代码
  7. 程序员,代码,理想,老男孩
  8. web测试的基本测试点
  9. LeetCode-Python-275. H指数 II
  10. 求职经验贴-描述笔者当时找工作情形
  11. 如何给微信公众号增加留言功能?
  12. 关于smtp发信的收件人to cc和bcc
  13. 淘宝聚划算怎么做?大神导航,一个神奇的网站从此开启大神之路
  14. 分数怎么约分成最简分数?其实很简单
  15. 什么是redis??
  16. SecureFx设置密钥登陆
  17. 戏剧的一年,记一段劳动仲裁经历
  18. 素描中的西红柿静物,这种画法才能画出果肉质感~
  19. 高级信息项目管理师规划
  20. linux内核 猪头 作用,漫谈Linux内核哈希表(1)

热门文章

  1. python秒表_使用Python创建秒表
  2. IDEA之保护眼睛的背景色
  3. Fuzz:Fuzz测试方法介绍
  4. ListView控件的使用方法,以及数据的绑定(关于会员等级)
  5. php Splqueue队列
  6. SpringThirdDay
  7. 杭电OJ——ACM 1003.Max Sum
  8. 谁有m55啊?帮忙测试一下我的这个游戏是否能在m55上运行。高分相送!
  9. Matlab答疑:一个关于符号表达式写法的简单问题
  10. Address already in use:9191