安全认证

概念

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

RBAC:Role-BasedAccess Control,基于角色的访问控制。RBAC认为权限授权实际上是Who、What、How的问题。在RBAC模型中,who、what、how构成了访问权限三元组,也就是“Who对What(Which)进行How的操作,也就是“主体”对“客体”的操作,其中 who——是权限的拥有者或主体(如:User、Role) what——是资源或对象(Resource、Class) how——是操作方式(CRUD)

so-fast微服务架构遵循RBAC设计理念,集成spring-security-oauth2、spring-security实现微服务集群的安全控制。

授权方式

so-fast微服务架构实现了基于Oauth2.0标准的四种授权:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password credentials)、客户端模式(client credentials),并规划在后续迭代中提供诸如微信认证、AppleID认证、微博认证等一些列的第三方授权功能。

授权方式控制

so-fast内置sys_oauth_client_details表,以灵活配置不同的授权场景。其可配置:授权方式、token的有效期、作用域、跳转url等授权信息。

当前版本只能手动修改数据库进行配置,后续迭代会提供超级管理页面来实现授权方式的可视化控制。

so-fast授权特点

基于UPMS设计,so-fast的安全认证被设计为客户端和服务器端同时持有Token令牌,在认证时需要检查Token的合法性以及时效性。

so-fast提供的安全认证主要涉及页面控制、API控制两个大类。通过上诉UPMS模块的设计可以看出,系统的所包含的各个页面、以及API接口均可在UPMS中进行维护,通过创建权限并指定权限范围就可以进行细粒度的页面与API的控制。so-fast的授权被设计为可应对多种情况的灵活配置

核心功能

请求授权

以最常见的密码模式为例。应用终端在向服务器申请授权时,需要向服务器提供三种信息:用于Basic认证客户端口令(sys_oauth_client_details表中配置的客户端以及客户端秘钥)、授权方式、用户名密码。其中客户端口令的设置需要进行base转码。

例如在sys_oauth_client_details表中配置了一各ID为web、秘钥为000000的客户端,并且配置该客户端支持密码模式,客户端口令的获取步骤如下:

1、字符串拼接得到(客户端ID:客户端秘钥):web:000000

2、上述字符串Base64转码得到:d2ViOjAwMDAwMA==

基于上诉准备工作,请求授权的接口信息如下:

请求方式:post

{
"grant_type":"password", //授权方式
"username":"admin2", //用户名
"password":"000000" //密码
}

​ 返回内容

{
    "status": 0,
    "code": null,
    "message": null,
    "data": {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJleHAiOjE2MTQ5MTU0OTgsInVzZXJOYW1lIjoiYWRtaW4yIiwidXNlcklkIjozLCJhdXRob3JpdGllcyI6WyJhZG1pbiJdLCJqdGkiOiI4MWNmYWRiZS1jZjQzLTRiYjAtYWZiYi0zYWIyM2M2M2E4OWMiLCJjbGllbnRfaWQiOiJ3ZWIifQ.h_4yFBsqzriN4fZYHk9c5GO2UVI3HaMAlGnvLKqWbwM",
        "jti": "81cfadbe-cf43-4bb0-afbb-3ab23c63a89c",
        "license": "so-fast",
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJhdGkiOiI4MWNmYWRiZS1jZjQzLTRiYjAtYWZiYi0zYWIyM2M2M2E4OWMiLCJ1c2VyTmFtZSI6ImFkbWluMiIsInVzZXJJZCI6MywiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiMGU1NTBmMzQtNTVmZC00MTFmLTlkMjYtNTA3ZTE0Mjg2ZjBkIiwiY2xpZW50X2lkIjoid2ViIn0.-ppOrp3oJE_97ABERPrzkbKmS0INbl-IW4cT-eBR8hw",
        "scope": [
            "read",
            "write"
        ],
        "token_type": "bearer",
        "expires_in": 4999,
        "userId": "3",
        "userName": "admin2"
    }
}

token刷新

在token的刷新场景同样需要提供用于Basic认证客户端口令(sys_oauth_client_details表中配置的客户端以及客户端秘钥),授权方式指定为refresh_token,并将应用端持有的refresh_token提交给服务器,详细如下:

{
    "grant_type":"refresh_token",
"refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJhdGkiOiI4MWNmYWRiZS1jZjQzLTRiYjAtYWZiYi0zYWIyM2M2M2E4OWMiLCJ1c2VyTmFtZSI6ImFkbWluMiIsInVzZXJJZCI6MywiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiMGU1NTBmMzQtNTVmZC00MTFmLTlkMjYtNTA3ZTE0Mjg2ZjBkIiwiY2xpZW50X2lkIjoid2ViIn0.-ppOrp3oJE_97ABERPrzkbKmS0INbl-IW4cT-eBR8hw"
}

​ 返回内容

{
    "status": 0,
    "code": null,
    "message": null,
    "data": {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJleHAiOjE2MTQ5MTU3NjAsInVzZXJOYW1lIjoiYWRtaW4yIiwidXNlcklkIjozLCJhdXRob3JpdGllcyI6WyJhZG1pbiJdLCJqdGkiOiI0MGYzNDc4MC1iMzIxLTQ5YWEtOWU3My1mNTk0Y2YxZGViNWYiLCJjbGllbnRfaWQiOiJ3ZWIifQ.6qaF_zi3113cEYhkjzA6XzvSJcgYEnLXo3mgUtOzRPw",
        "jti": "40f34780-b321-49aa-9e73-f594cf1deb5f",
        "license": "so-fast",
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJhdGkiOiI0MGYzNDc4MC1iMzIxLTQ5YWEtOWU3My1mNTk0Y2YxZGViNWYiLCJ1c2VyTmFtZSI6ImFkbWluMiIsInVzZXJJZCI6MywiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiMGU1NTBmMzQtNTVmZC00MTFmLTlkMjYtNTA3ZTE0Mjg2ZjBkIiwiY2xpZW50X2lkIjoid2ViIn0.iZ78-f1YSH8H_hu04en7qfLVMly409PfuiP5BHt3t5w",
        "scope": [
            "read",
            "write"
        ],
        "token_type": "bearer",
        "expires_in": 4999,
        "userId": "3",
        "userName": "admin2"
    }
}

业务请求

在普通业务场景下,应用端只需向服务器提供有效的token即可,详细如下:

  • URL:http://XXXXX/xxxxx/xxxxx/page

  • 请求方式:post、get等

  • 参数:header

    Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlIjoic28tZmFzdCIsInVzZXJfbmFtZSI6ImFkbWluMiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJleHAiOjE2MTQ3NTk5OTksInVzZXJOYW1lIjoiYWRtaW4yIiwidXNlcklkIjozLCJhdXRob3JpdGllcyI6WyJhZG1pbiJdLCJqdGkiOiI5MzYxYTk5OS02NWZkLTQyZGYtOWIxMS02MDk1MTgxNjkyZGQiLCJjbGllbnRfaWQiOiJ3ZWIifQ._V-g8_OZQYyy_qfpBpnFx_z5ithPRBukNG8x-sz2j38
    Content-Type:application/json
    

    参数:jsonbody

    返回内容

    {
        略
    }
    
异常返回
  • 如登录时用户名口令错误,请求状态为200,返回结果如下:
{
    "code": "Err.E001",
    "message": "登陆失败,请确认用户名口令.",
    "status": 1
}
  • 如验证码错误,请求状态为200,返回结果如下
{
    "code": "Err.E010",
    "message": "请输入正确的验证码.",
    "status": 1
}
{
    "code": "Err.E011",
    "message": "验证码已过期.",
    "status": 1
}
  • 如访问白名单以外的API时不携带token,则会返回:401错误,详细内容为:
{
    "code": "Err.E003",
    "message": "TOKEN非法或已过期.",
    "status": 1
}
  • 如客户端持有的token过期,则会返回:401错误,详细内容为:
{
    "code": "Err.E003",
    "message": "TOKEN非法或已过期.",
    "status": 1
}
  • 如使用非本系统授权的token,则会返回:401错误,详细内容为:
{
    "code": "Err.E003",
    "message": "TOKEN非法或已过期.",
    "status": 1
}
  • 如访问受限的API,则会返回:403错误,详细内容为:
{
    "code": "Err.E002",
    "message": "访问受限,请确认权限.",
    "status": 1
}
服务保护

微服务集群中的所有服务理论上都需要被认证服务器保护,so-fast被设计为基于so-fast自有注解EnableSolResourceServer的方式开启服务的安全防护。详细如下:

@EnableSwagger2
@EnableSolFeign
@EnableDiscoveryClient
@EnableSolResourceServer
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class SoFastUpmsApplication {

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

}
安全配置

与传统Oauth2.0不同的是,so-fast提供用户踢出和禁止登录功能,以灵活地应对客户需求。so-fast内置安全相关的默认配置,各项目可依据自身需求酌情修改,配置文件如下:

#安全配置
sofast:
  security:
    jwt:
      #token版权声明
      license: so-fast
      #token加密
      sing-key: 09152205192rytt103080514ShuCCCCC---henLLLLVVVVdedoo(rtertter)dds
    need:
      #token中知否植入用户信息
      user-info: true
      #是否对API进行细粒度的判定
      details-authority: true
    #token校验配置
    limit:
      #是否禁止同一账号多终端登录
      multiple-login: false
      #当检测到同时登录时,是禁止登录还是踢出已登录。此项设置为true时,踢出前一个登录终端
      kicked-out: true
    #token校验配置
    token-check:
      #客户端ID
      client-id: web
      #客户端秘钥
      client-secret: "000000"
      #是否使用服务名指定认证服务器,此项设置为true是,check-token-endpoint-url请设置为集群中的认证服务名称
      check-token-by-service-name: true
      #认证服务地址
      check-token-endpoint-url: http://so-fast-uaa/oauth/check_token
    #服务白名单
    white-list:

sing-key为token的签名秘钥,切记妥善保存。

token信息的控制部分在UAA工程内覆盖配置,比如当系统不需要在token中织入用户信息并且禁止多终端登录时(禁止登录)时,可在UAA工程的配置文件中添加以下配置:

#安全配置
sofast:
  security:
    need:
      #token中知否植入用户信息
      user-info: false
    limit:
      #是否禁止同一账号多终端登录
      multiple-login: true
      #当检测到同时登录时,是禁止登录还是踢出已登录。此项设置为true时,踢出前一个登录终端
      kicked-out: false

集中鉴权配置在业务服务中可进行配置覆盖,示例如下:

#安全配置
sofast:
  security:
    token-check:
      #客户端ID
      client-id: web
      #客户端秘钥
      client-secret: "000000"
      #是否使用服务名指定认证服务器,此项设置为true是,check-token-endpoint-url请设置为集群中的认证服务名称
      check-token-by-service-name: true
      #认证服务地址
      check-token-endpoint-url: http://so-fast-uaa/oauth/check_token
    #服务白名单
    white-list:/aaaa/**
Copyright © 2020. 恩梯梯数据(中国)信息技术有限公司. all right reserved,powered by Gitbook该文件修订时间: 2021-03-08 14:45:37

results matching ""

    No results matching ""