OIDC的集成到扩展

OIDC全程为OpenID Connect,其在实际应用中充当着授权服务器和OpenID Connect身份提供者

其利用第三方客户端来提供用户的身份认证,并将对应的身份认证信息传递给客户端,适用于多种客户

其架构图如下:

图片

从上图可以看出

我们将大致的交互对象分为,用户,客户端,认证服务器,

而整体请求流转的图如下:

图片

我们将按照上面的图,说一下整体的请求流程

1.用户请求客户端登录,客户端返回重定向网址,让用户请求认证服务器

2.用户在认证服务器完成请求后,返回请求给客户端,携带者认证信息

3.客户端拿着认证信息去认证服务器换取用户资源信息,从而完成用户信息的获取

在上面的第二步中,OIDC为了防止重放攻击,更加细化为了如下的步骤

图片

上图中的2即用户登录完成之后

uaa会返回一个认证Code,这个Code并不是Token,无法用户获取用户Info

我们需要拿这个Code去再次请求uaa,获取真正的Token,这个Code也只能使用一次,避免上面说的重放攻击

总结一下上面的流程,

1.用户请求客户端

2.客户端重定向到UAA认证界面(携带回调地址,客户端id等信息)

3.用户登录完成,UAA重定向到客户端,携带返回id(利用回调地址)

4.客户端利用id从UAA上换取Token

5.客户端拿到Token后去UAA换取用户信息

6.登录完成

说完了流程,我们先看下网络的请求和返回详情,也是对应着上面的流程

1.用户请求客户端

这一步就是简单的请求,pass

2.交由客户端重定向到认证模块,这一步给用户的重定向格式基本如下

客户端id需要提前在认证提供商上进行登记

scope 是最终能够获取到用户info的范围

其次就是

redirect_uri

也要求在认证提供商提前登记,这里认证提供商会进行校验,方便登录成功返回

返回结果中

携带着上述说的id,方便后面请求token

拿到了id之后,就是client需要做的剩余流程了

根据id获取token的请求如下

curl -X POST \

<AMBaseURL>/oauth2/<realmPath>/access_token \

-H “authorization: Basic <BASE64-encoded-client-credentials>” \

-H “content-type: application/x-www-form-urlencoded” \

–data “grant_type=authorization_code&code=<auth-code>&redirect_uri=<redirect-uri>”

上面请求中携带了部分信息,主要包含

header中的authorization 是由client id + client secret 拼接后的字符串 利用Base 64进行了编码

然后是之前返回的code,以及自己的redirect_uri,方便客户端校验

获取到的响应基本如下

{

“access_token”: “<access-token>”,

“refresh_token”: “<refresh-token>”,

“scope”: “openid profile”,

“id_token”: “<oidc-token>”,

“token_type”: “Bearer”,

“expires_in”: 3599,

“nonce”: “<nonce>”

}

上面返回的了accessToken和refreshToken

可以拿这些去获取UserInfo和accessToken

对于userinfo的权限获取,可以执行如下的请求

curl -X GET \

<AMBaseURL>/oauth2/<realmPath>/userinfo \

-H “authorization: Bearer <access-token>”

获取的必然就是用户的info

{

“name”: “<user-fullName>”,

“sub”: “<username>”

}

其次是refreshToken

其请求如下:

curl -X POST \

<AMBaseURL>/oauth2/<realmPath>/access_token \

-H “authorization: Basic <BASE64-encoded-client-credentials>” \

-H “content-type: application/x-www-form-urlencoded” \

–data “grant_type=refresh_token&refresh_token=<refresh-token>&redirect_uri=<redirect-uri>”

然后获取到新的token响应

{

“access_token”: “<access-token>”,

“scope”: “openid profile”,

“id_token”: “<oidc-token>”,

“token_type”: “Bearer”,

“expires_in”: 3599

}

在获取到用户信息和userinfo之后,就可以交给用户token,进行前后端交互了

那么对应的oidc和Spring Security如何整合呢?

我们拿okta这个认证提供商的集成来作为示例,看一下如何进行集成的

1.增加对应的maven依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-oauth2-client</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-security</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.security</groupId>

<artifactId>spring-security-config</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.security</groupId>

<artifactId>spring-security-oauth2-jose</artifactId>

</dependency>

然后在配置文件声明对应的clientId clientSecret  回调地址 及 提供商地址

spring:

thymeleaf:

cache: false

security:

oauth2:

client:

registration:

okta:

client-id: 7d6ecff6-7eab-424d-b704-6e55dd87dd19

client-secret: RBELbgM0VEC1MW88eIFaFV0kIplsqa8bcUylc2Ax

authorization-grant-type: authorization_code

redirect-uri: ‘https://localhost:88/iwaLogin

response-type: code

scope: email

provider:

okta:

authorization-uri:

token-uri:

user-info-uri:

jwk-set-uri:

然后配置WebSecurityConfig

http.authorizeRequests()

.anyRequest().authenticated()

.and()

.oauth2Login()

.redirectionEndpoint()

.baseUri(“/api/iwaLogin”)

之后就直接尝试访问

https://localhost:88/oauth2/authorization/okta

获取重定向的地址,登录完成后会尝试回调上面的结果

之后交给框架完成剩下的工作了

这就完成了简单的集成,但是由于Spring Security提供的并不是前后端分离的,所以还需要进行一些扩展

对于这些扩展,我们留在下篇文章讲

发表评论

邮箱地址不会被公开。 必填项已用*标注