前几篇文章对GAF的各个模块功能进行详细介绍,并通过管网示例, 实践了扩展开发流程。接下来重点介绍GAF的认证体系,以及如何与其他系统相互之间对接认证,解决系统之间的如何共享用户体系、单点登录问题。
在认证微服务模块(gaf-authentication
), 使用spring-security
+oauth2.0
,提供认证、oauth2、token、用户相关的接口。相关接口可查看API文档
在网关模块,使用spring-cloud-gateway
+一系列自定义过滤器
,在网关处进行统一认证。网关调用认证微服务的接口进行认证校验,并获取用户信息,传递给下游微服务,以便下游微服务使用。
1. 通过用户名密码登录,后续请求使用cookie
使用POST方式发送请求/api/authentication/login/username_password
到网关或者前端,进行登录。后端返回cookie,后续所有请求携带cookie,则可通过认证校验,并获取到用户信息。
2.通过用户名密码获取jwt token, 后续请求使用jwt token
使用POST方式发送请求/api/authentication/token
到网关或者前端,从返回内容中的data.access_token
字段获取jwt。后续所有请求增加请求头Authorization Bearer ${获取的jwt}
,则可通过认证校验,并获取到用户信息。
这种方式,适用于其他系统调用GAF系统的接口。
认证组件(gaf-authentication)中,提供了第三方登录配置,支持OpenId和OAuth2协议。
配置说明
yaml格式
login:
enable-third-party: false #是否开启第三方登录
third-party-login-model: mutiple # 第三方登录模式 single (表示只有一种第三方登录) 或者 mutiple (第三方登录可以存在多种)
third-party-name: oidc:keycloak # 第三方登录名 由下面third-party信息构成 例如oidc:keycloak或者oauth2:github
third-party:
oidc:
keycloak:
order: 1 # 排序序号
iconUrl: https://www.keycloak.org/resources/favicon.ico # 图标地址
provider:
authorizationUri: http://xxx:xx/auth/realms/master/protocol/openid-connect/auth
tokenUri: http://xxx:xx/auth/realms/master/protocol/openid-connect/token # 获取token的接口
userInfoUri: http://xxx:xx/auth/realms/master/protocol/openid-connect/userinfo # 获取用户信息的接口
userNameAttribute: preferred_username # 返回用户信息中代表用户名的属性名
registration:
clientId: my-gaf-authentication # 在第三方登录中心 提前注册的客户端id
clientSecret: c140a5f3-64cf-4613-9faa-49c880b3008e # 在第三方登录中心 提前注册的客户端密钥
redirectUri: http://${gaf主机ip:端口}/api/authentication/login/callback/oidc # 回调地址。
scope: ["roles","email","profile","web-origins"]
oauth2:
github:
order: 2
iconUrl: https://img.icons8.com/fluency/48/ffffff/github.png # 图标地址
provider:
authorizationUri: https://github.com/login/oauth/authorize
tokenUri: https://github.com/login/oauth/access_token # 获取token的接口
userInfoUri: https://api.github.com/user # 获取用户信息的接口
userNameAttribute: login # 返回用户信息中代表用户名的属性名
registration:
clientId: 3258e18d4d57bab07630 # 在第三方登录中心 提前注册的客户端id
clientSecret: 5665dc4d3a767e88e9b4af1a0893585e932548e5 # 在第三方登录中心 提前注册的客户端密钥
redirectUri: http://${gaf主机ip:端口}/api/authentication/login/callback/oauth2 # 回调地址
scope: [ "read:user" ]
准备好所需配置的值后,把yaml格式的配置转换为properties格式的配置,可在GAF的微服务配置中心修改gaf-authentication中login.third-party
相关的配置,开启第三方登录,修改完成后保存,点击发布
按钮直接生效。效果图如下。
以spring security 5.2.x分支的oauth2登录样例为例子,在配置了默认的四种第三方登录google、github、facebook、okta的情况下,增加GAF第三方登录配置,以GAF作为登录中心进行登录。
在进行配置之前,需要联系GAF的管理员,注册客户端,获取客户端id和客户端密钥。
GAF管理员需在GAF的数据库的oauth_client_details
表中注册客户端信息。其需要填写的字段包括
"client_id" 客户端id,用于唯一标识每一个客户端(client),必须唯一,不能为空.,
"resource_ids" 客户端所能访问的资源id集合,多个资源时用逗号(,)分隔,如: "unity-resource,mobile-resource".,
"client_secret" 客户端(client)的访问密匙 必须填写,
"scope" 指定客户端申请的权限范围,可选值包括read,write,trust;若有多个权限范围用逗号(,)分隔,如: "read,write"
"authorized_grant_types"指定客户端支持的grant_type,可选值包括authorization_code,password,refresh_token,implicit,client_credentials, 若支持多个grant_type用逗号(,)分隔,如: "authorization_code,password".
"web_server_redirect_uri" 客户端的重定向URI 当grant_type为authorization_code或implicit时, 在Oauth的流程中会使用并检查与注册时填写的redirect_uri是否一致,
"authorities" varchar(256) 指定客户端所拥有的Spring Security的权限值,可选, 若有多个权限值,用逗号(,)分隔, 如: "ROLE_UNITY,ROLE_USER",
"access_token_validity" 设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 12, 12小时).,
"refresh_token_validity" 设定客户端的refresh_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 24 * 30, 30天).,
"additional_information"这是一个预留的字段,在Oauth的流程中没有实际的使用,可选,但若设置值,必须是JSON格式的数据,如:
{"country":"CN","country_code":"086"} ,
"autoapprove" 设置用户是否自动Approval操作, 默认值为 'false', 可选值包括 'true','false', 'read','write'.
该字段只适用于grant_type="authorization_code"的情况,当用户登录成功后,若该值为'true'或支持的scope值,则会跳过用户Approve的页面, 直接授权,
字段填写举例
client_id custom_client
resource_ids custom_client_rid
client_secret $2a$10$cfHuOZPGdPU1LfPOsltQ9.FOfA6iD9R6FuQR.5rjd5AEd7qOl4eCq(这里是BCrypt加密后的结果,需将原始客户端密钥手动用BCrypt加密)
scope all
authorized_grant_types password,authorization_code,refresh_token
web_server_redirect_uri http://localhost:8080/login/oauth2/code/gaf
authorities
access_token_validity 7200
refresh_token_validity 72000
additional_information
autoapprove true
此时GAF管理员返回客户端id和客户端密钥原始值给申请者。例如custom_client/123
在spring security 5.2.x分支的oauth2登录样例的配置文件中增加gaf相关的配置,完整配置如下。
server:
port: 8080
logging:
level:
root: INFO
org.springframework.web: INFO
org.springframework.security: INFO
# org.springframework.boot.autoconfigure: DEBUG
spring:
thymeleaf:
cache: false
security:
oauth2:
client:
registration:
google:
client-id: your-app-client-id
client-secret: your-app-client-secret
github:
client-id: your-app-client-id
client-secret: your-app-client-secret
facebook:
client-id: your-app-client-id
client-secret: your-app-client-secret
okta:
client-id: your-app-client-id
client-secret: your-app-client-secret
gaf: # 增加使用gaf作为登录中心相关的配置
provider: gaf # 值对应下面的provider: gaf
authorizationGrantType: authorization_code # 授权类型,授权码模式
clientAuthenticationMethod: post #客户端认证方式 采用post请求
client-id: custom_client # GAF里注册的客户端id
client-secret: 123 # GAF里注册的客户端密钥(加密前的)
redirectUri: http://localhost:8080/login/oauth2/code/gaf # 授权码回调地址
scope: all # 授权的权限
clientName: custom_client # 用于显示
provider:
okta:
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
gaf:
authorization-uri: http://gaf.net.cn/api/oauth/authorize # GAF授权接口
token-uri: http://gaf.net.cn/api/oauth/token # 根据授权码获取token的接口
user-info-uri: http://gaf.net.cn/api/authentication/user/info # 根据token获取用户信息的接口
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys #暂时无需设置
user-name-attribute: name # 返回的用户信息中的代表用户名的属性名