如何访问被Keycloak保护的后端API

1,389 阅读3分钟

后端项目集成Keycloak之后我们是无法直接访问后端的接口或者页面的。此时必须先获取到token然后携带着token去访问接口。 本篇我们讲述两种获取token然后请求的方式

  1. 使用HTTP请求获取token
  2. 使用Postman的认证工具

一、使用HTTP请求获取token

后端集成keycloak时,我们一般会把访问类型设置为confidential或者bearer-only类型的;前端项目一般是需要设置为public类型。

在后端正确地集成了Keycloak,并把访问类型设置为bearer-only之后,我们就可以通过下面的url获取token:

POST http://{ServerUrl}:8080/auth/realms/{realm}/protocol/openid-connect/token

其中需要输入你当前keycloak服务器的URL地址,realm需要设置成你后端项目所在的realm名。 配置好URL之后我们需要填写表单参数。这里需要说明下,我此处只使用了Password credentials方式获取token,也就是使用用户名密码去获取token的方式。此方式需要四个参数:

参数名参数值
grant_typepassword
username{你的用户名}
password{你的密码}
client_id你keycloak域中访问类型为public的client_id

这里grant_type的值是固定的,写password就可以。用户名密码是你当前realm中用户的账户和密码。这里最重要的是client_id。大部分刚接触keycloak的开发人员会以为这里填写我访问的client就可以了。其实这是不对的。 bearer-only访问类型的后端是没有登录界面的,因此我们需要一个public的客户端来获取token。 这里顺带提一句,如果你的后端是非前后端分离的项目,那你应该把客户端设置成public类型。

假定你现在有两个客户端,一个叫fronted,一个叫backend。那么获取token时,你应该使用fronted这个客户端获取发送token请求。下面是一个样例:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0NE81OGVoNldXTG13NTdiSXNZMjdNTWR1bUg0dW9oMlVQeFhMS1UtUWFVIn0.eyJqdGkiOiJmZTA2ZjMzZS0yOWRmLTQ4MTItYWFkNi1mYzY3ZDhhYTIwNjQiLCJleHAiOjE1ODU0ODk5NDIsIm5iZiI6MCwiaWF0IjoxNTg1NDg4NzQyLCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjpbInVzZXItY2VudGVyIiwidGVzdC1yZWFsbSIsIm1hc3Rlci1yZWFsbSIsImFjY291bnQiLCJhaW9wcy1yZWFsbSJdLCJzdWIiOiIwZTZlNzBiOS02ZWNmLTRiNjAtOWUxYy1kZDVhMzk0YWNlNTMiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhaW9wcy13ZWIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJkYWZkZTA2Ny00ZjFlLTQ2NjQtOTFhNC02NmIwNDZmMDZmZGIiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImNyZWF0ZS1yZWFsbSIsIm9mZmxpbmVfYWNjZXNzIiwiYWRtaW4iLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InVzZXItY2VudGVyIjp7InJvbGVzIjpbInN1cGVyX3JvbGUiXX0sInRlc3QtcmVhbG0iOnsicm9sZXMiOlsidmlldy1pZGVudGl0eS1wcm92aWRlcnMiLCJ2aWV3LXJlYWxtIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJjcmVhdGUtY2xpZW50IiwibWFuYWdlLXVzZXJzIiwicXVlcnktcmVhbG1zIiwidmlldy1hdXRob3JpemF0aW9uIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LXVzZXJzIiwibWFuYWdlLWV2ZW50cyIsIm1hbmFnZS1yZWFsbSIsInZpZXctZXZlbnRzIiwidmlldy11c2VycyIsInZpZXctY2xpZW50cyIsIm1hbmFnZS1hdXRob3JpemF0aW9uIiwibWFuYWdlLWNsaWVudHMiLCJxdWVyeS1ncm91cHMiXX0sIm1hc3Rlci1yZWFsbSI6eyJyb2xlcyI6WyJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19LCJhaW9wcy1yZWFsbSI6eyJyb2xlcyI6WyJ2aWV3LXJlYWxtIiwidmlldy1pZGVudGl0eS1wcm92aWRlcnMiLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoicm9vdCIsImxvY2FsZSI6InpoLUNOIiwiZW1haWwiOiIxMjNAcXEuY29tIn0.SQ130RR2EJG8NPjNopW3KOPBfueLowUnLHhaDlfjImHc9GqTN479GoMW_bR_doj28AezsfBD5G-qTU-U3pqawVVbjgmzMW31JF0vZtQnkCsnI7GOAJtTUM4a8teMs9eNOLR9t1CyWbSeGlIhu-kYk_O_mgxTxenfrq8H3DJ4xBuU8fKopdXoGMIcVNePujngCOYkCQBXzZceNrGXy0_7lPs7_BaDUaJ7OEVhpY8-tSKRVU7a8XOhKeSllzepiWMeEA3fhgW-A1yQz14ODEW9Dbh9axtdJ7RyhvpNH3dDa5XIIzYx8-zpn13IsbA2lWMY1WihL4I2RPyE6iEl9qSoYg",
    "expires_in": 1200,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmNmEzMjMwNy03Y2YxLTQxNmYtOGEyYy1jMWE1NGMxZDA5NTIifQ.eyJqdGkiOiJkZTAzMjA2NC0yMjFiLTRmYTItYjgyZC03MjI3YzAzOWI0N2QiLCJleHAiOjE1ODU0OTA1NDIsIm5iZiI6MCwiaWF0IjoxNTg1NDg4NzQyLCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiaHR0cDovLzEyNy4wLjAuMTo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjBlNmU3MGI5LTZlY2YtNGI2MC05ZTFjLWRkNWEzOTRhY2U1MyIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhaW9wcy13ZWIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJkYWZkZTA2Ny00ZjFlLTQ2NjQtOTFhNC02NmIwNDZmMDZmZGIiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwib2ZmbGluZV9hY2Nlc3MiLCJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidXNlci1jZW50ZXIiOnsicm9sZXMiOlsic3VwZXJfcm9sZSJdfSwidGVzdC1yZWFsbSI6eyJyb2xlcyI6WyJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbInZpZXctaWRlbnRpdHktcHJvdmlkZXJzIiwidmlldy1yZWFsbSIsIm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInF1ZXJ5LXJlYWxtcyIsInZpZXctYXV0aG9yaXphdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycyIsIm1hbmFnZS1ldmVudHMiLCJtYW5hZ2UtcmVhbG0iLCJ2aWV3LWV2ZW50cyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtYXV0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX0sImFpb3BzLXJlYWxtIjp7InJvbGVzIjpbInZpZXctcmVhbG0iLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsIm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInF1ZXJ5LXJlYWxtcyIsInZpZXctYXV0aG9yaXphdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycyIsIm1hbmFnZS1ldmVudHMiLCJtYW5hZ2UtcmVhbG0iLCJ2aWV3LWV2ZW50cyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtYXV0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIn0.uSd2u3m7AZUJmjq8OmV99ORw9JPGokGJ9S5gUDd7wVo",
    "token_type": "bearer",
    "not-before-policy": 1583228262,
    "session_state": "dafde067-4f1e-4664-91a4-66b046f06fdb",
    "scope": "email profile"
}

这里其实你需要关注的是access_tokentoken_type。当你成功获取到token之后,你需要的是拼接token成如下形式。

Bearer {access_token}

然后将这个token放入到你请求后端接口HTTP请求的Headers的Authorization请求头里面。 然后你就可以成功的访问到你后端的API了。

二、使用Postman的认证工具

Keycloak的认证是基于OAuth 2.0协议的,这也就意味着获取keycloak的token的过程是一个固定的流程。那么我们如何使用Postman访问API呢。 首先我们先选择authorization选项卡,然后在TYPE中选择OAuth 2.0。 image.png 然后我们点击橙色的按钮Get new access tokenimage.png

在这个界面上,我们先选择Grant Type为Password credentials,再依次填入Access Token URL,Username,Password,Client ID。然后就可以点击获取token的按钮了。 如果获取成功的话,应该显示获取到的token。然后向下滚动点击use token,就可以访问你需要的API了。

参考资料

grant_type为client_credentials和password二者的区别