I went to "OAuth & OIDC Study Group (FAPI & CIBA Special!)" held on 3/28 (Thursday).
The organizer is Authlete, a company that provides Baas that can build OAuth and OpenID Connect (OIDC) authorization servers. Since the cloud service of Authlete was compatible with CIBA, which is a new specification of OAuth / OIDC, it was a study session that also served as an introduction to the cloud service.
Aside from my OAuth, CIBA was my first look, so I learned a lot. Thank you to the people at Authlete who hosted the study session.
This time it was about FAPI (Financial-grade API) and CIBA (Client Initiated Backchannel Authentication), but regarding FAPI, "Restrictions when using OAuth / OIDC in places with higher security requirements such as the financial industry" is specified. You can think of it as a converted product. An easy-to-understand example is that OAuth Client client authentication when taking a token is not basic authentication, so prepare an X.509 certificate, etc. ..
CIBA stands for OpenID Connect Client Initiated Backchannel Authentication Flow --Core 1.0. Whereas OAuth / OIDC (so-called RFC 6749) was ** a premise processing sequence using WEB browser redirection ** [^ 1] , CIBA has a processing sequence of ** sending an authentication request to the back channel authentication endpoint ** and ** notifying the pre-registered user's authentication device "Agree?" **. Is a feature. ..
[^ 1]: It is impressive that the person who was on the stage explained this processing sequence as ** OAuth Dance ** :-)
This allows, for example,
--When you tell Alexa "I'll buy xxx, pay ¥ 3,000!", The Alexa app sends an authentication request to the authorization server. --The authorization server notifies the authentication device (smartphone app) of "Allow?" --If the user presses OK on the smartphone, the payment will be completed.
What a processing sequence that does not require browser redirection can be realized. Well, it's really convenient.
The specific processing sequence looks like this. ..
Well, before, I had an opportunity to touch the Authlete service in a certain development project, and I posted the construction procedure at that time to Qiita, although it is about Hello World.
This time, I was lucky enough to have the opportunity to touch the CIBA-compatible Authlete service, so I will record the construction procedure as a reminder. (Thank you!)
It is a prerequisite knowledge for reading the construction procedure below, but I will proceed on the assumption that I have OAuth / OIDC and CIBA to some extent. For example, you generally know the processing sequence of Authorization Code Grant Flow or CIBA Flow.
Now, the following is the authorization code grant flow so-called OAuth Dance processing sequence. The position of Authlete is also written together.
--Authorization Code Grant Flow processing sequence
This time, by touching the CIBA-compatible Authlete, I will try to implement the following ** CIBA Flow processing sequence (described earlier) and get an access token **. For authentication devices, there is an authentication device simulator site, so use that site.
--CIBA Flow processing sequence
In addition, there are three modes of poll, ping or push as a way for the OAuth Client to know the "result of the user's operation on the authentication device (authorization, denial, timeout etc.)". /openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.5), but ** this time I will use "poll" **. In this mode, the OAuth Client polls the authorization server to know the user's operation results. I haven't tried ping and push yet, but in the case of ping, the authorization server sends an HTTPS notification saying "Come to get it, good", and push seems to send the access token as it is. (Reference: 9. Client Notification Endpoint)
The environment around this time is as follows.
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.4
BuildVersion: 18E226
$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
$ mvn --version
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-25T03:41:47+09:00)
$
$ curl --version
curl 7.54.0 (x86_64-apple-darwin18.0) libcurl/7.54.0 LibreSSL/2.6.5 zlib/1.2.11 nghttp2/1.24.1
$
$ jq --version
jq-1.6
$
I'm doing it above, but if maven, curl, jq (and git) work, I think anything including the OS is OK.
In addition, although it is a character such as various servers, in previous article
Use | Server name | URL |
---|---|---|
Authorization server. A server that manages authorization information for each user ID. | java-oauth-server | http://oauth.example.com:8080/ |
Resource server. A server with data and functions for each user ID. | java-resource-server | http://resource.example.com:8081/ |
Web application. Web application that uses resources of resource server | java-oauth-client | http://client.example.com:8082/ |
However, this time, since the article is about getting the access token (or id_token), the resource server is omitted and the curl command is used as the OAuth Client. Therefore, it has a simple structure as shown below.
Use | Server name | URL |
---|---|---|
Authorization server. A server that manages authorization information for each user ID. | java-oauth-server | http://localhost:8080/ |
Resource server. A server with data and functions for each user ID. | abridgement | - |
OAuth Client. An app that uses resources from the resource server. | This time curl | - |
The general flow is basically the same as the conventional usage of Authlete.
However, as described in the article Making a CIBA-compatible authorization server using Authlete (Human in) , It seems that you need to contact Authlete to sign up for your account.
Therefore, in this article, the account has been signed up, and the following information has been obtained from the CIBA-compatible Authlete site (usually https://so.authlete.com/, but the CIBA-compatible version has a different URL). I will proceed on the premise that.
--API key / API secret of the authorization server associated with that account
API key | API secret |
---|---|
116xxxxxxxx | sZUkxxxxxxxxxxxxxxxxxxx |
--Client ID / client secret of OAuth Client registered in the authorization server
Client ID | Client secret |
---|---|
249xxxxxxx | WUItxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
By the way, you can check the API key / API secret of the authorization server from the following service list >> service details.
You can also check the client ID / client secret of the OAuth Client registered on the authorization server from the app list >> app details on the client app developer console.
Now, here are some preferences to enable CIBA on the Authlete website.
The site (service administrator console) that confirmed the API key / API secret on the authorization server side Go to the "Service List >> Service Details >> CIBA" tab and go to
item | value |
---|---|
Token delivery mode to support | POLL,PING,PUSH |
User code support | to support |
Choose.
Transition to "App list >> App details" on the site (client app developer console) where the client ID / client secret of OAuth Client is confirmed.
On the "Basic Information" tab
item | value |
---|---|
Client type | CONFIDENTIAL |
Choose.
On the "Authorization" tab
item | value |
---|---|
Client authentication method | CLIENT_SECRET_BASIC |
Choose.
On the "CIBA" tab
item | value |
---|---|
Token delivery mode | POLL |
User code request | Request |
Choose.
This completes the environment settings for the authorization server and OAuth Client when operating in POLL mode.
First, build an authorization server. Clone the GitHub repository and set the API key, API secret, and base_url in the configuration file (authlete.properties).
$ git clone https://github.com/authlete/java-oauth-server.git
$ cd java-oauth-server
$ cat authlete.properties
service.api_key =116xxxxxxxx ← Please change to the correct API key
service.api_secret =sZUkxxxxxxxxxxxxxxxxxxx ← Please change to the correct API secret
base_url = https://api.authlete.com ← Please change to a URL that supports CIBA(Contact Authlete for the value)
start up.
$ mvn clean jetty:run -Dauthlete.ad.workspace=masatomix/testProject ← Argument is a value to be set in the simulator that will come later
This completes the construction of the authorization server.
The authorization server that receives the backchannel authentication request sends a notification to the authentication device "Can I allow it?", But the code of the cloned authorization server is [Authlete CIBA Simulator](https: //) by default. Notifications are now sent to cibasim.authlete.com/). So we will set up the simulator.
Go to https://cibasim.authlete.com/ and set the argument above,
Namespace | Project |
---|---|
masatomix | testProject |
Specify and click "Create". (The screen capture below is "Open" after it is created.)
Then, the screen will change to the Authentication Device (AD) simulator screen. The authorization server provided by Authlete has dummy user authentication coded on it.
User ID | User Code |
---|---|
1001 | 675325 |
You can log in with. Therefore, specify the User ID "1001" as shown in the capture and click "Launch AD simulator".
The simulator is waiting. Since OAuth authentication / authorization is performed on this screen, please leave the screen open (it seems that a push notification will come here via WebSocket when the authorization server receives a backchannel authentication request).
By the way, if you open this screen on your smartphone, you will feel a sense of reality. When you send an authentication request from curl on a PC that has nothing to do with it, it looks like a notification will come to your smartphone.
Now, let's send an authentication request to the authorization server.
$ clientId=249xxxxxxx ← Client ID
$ clientSecret=WUItxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ← Client secret
$ curl http://localhost:8080/api/backchannel/authentication -X POST \
--user ${clientId}:${clientSecret} \
-d 'login_hint=1001' \
-d 'user_code=675325' \
-d 'scope=openid'
{
"auth_req_id": "Xe250q9AoSdUL_xohrPm8txYNUo8VlddhLv1ENUY6SM",
"interval": 5,
"expires_in": 600
}
$
I got the auth_req_id (authentication request ID). Make a note of it as you will use it later.
When you send the authentication request, you should see the authorization screen that you are familiar with with OAuth in the simulator. Select "Allow" this time.
Now that you have the user's authorization, you can use the auth_req_id you just saw. Now that you are ready to get the token, send a token request.
$ clientId=249xxxxxxx ← Client ID
$ clientSecret=WUItxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ← Client secret
$ curl http://localhost:8080/api/token -X POST \
--user ${clientId}:${clientSecret} \
-H 'Content-type: application/x-www-form-urlencoded' \
-d 'auth_req_id=Xe250q9AoSdUL_xohrPm8txYNUo8VlddhLv1ENUY6SM' \
-d 'grant_type=urn:openid:params:grant-type:ciba'
{
"access_token":"ldofpBo8hO67CNr4sE_Cibt1FYZ8RpQCIPVlUaeokks",
"refresh_token":"U0JyhKdXh-h3h6hDLiu3eart9RpEwnSClMtgGjAFu5o",
"scope":"openid",
"id_token":
"eyJhbGciOiJIUzI1NiJ9.eyJhdF9oYXNoIjoiRkxwdFBEaWlMbUcwdkVLWFZndjBUZyIsInN1YiI6IjEwMDEiLCJhdWQiOiIyNDkzOTMxNjU5OTciLCJhdXRoX3RpbWUiOjE1NTM4NTE3MjQsImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTUzOTM4MTM0LCJpYXQiOjE1NTM4NTE3MzR9.7G_VfqlSlDd0cOSjZaRorSrbcH3PoKneM_YalCpFHig","token_type":"Bearer","expires_in":86400
}
You got an access token! Since the scope is set to openid this time, id_token is also obtained.
$ echo eyJhdF9oYXNoIjoiRkxwdFBEaWlMbUcwdkVLWFZndjBUZyIsInN1YiI6IjEwMDEiLCJhdWQiOiIyNDkzOTMxNjU5OTciLCJhdXRoX3RpbWUiOjE1NTM4NTE3MjQsImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTUzOTM4MTM0LCJpYXQiOjE1NTM4NTE3MzR9 | base64 -D | jq
{
"at_hash": "FLptPDiiLmG0vEKXVgv0Tg",
"sub": "1001",
"aud": "249393165997",
"auth_time": 1553851724,
"iss": "https://authlete.com",
"exp": 1553938134,
"iat": 1553851734
}
Since this process is done in poll among the push, ping, and poll modes, you will not be notified if the authentication request is OK. So in reality, it seems that the app will need to poll after sending the authentication request.
For example, try running the following shell.
$ cat ciba_request.sh
#!/bin/bash
clientId=249xxxxxxx ← Client ID
clientSecret=WUItxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ← Client secret
login_hint=1001
user_code=675325
backchannelReq=`cat << EOS
curl http://localhost:8080/api/backchannel/authentication -X POST \
--user ${clientId}:${clientSecret} \
-d 'login_hint=${login_hint}' \
-d 'user_code=${user_code}' \
-d 'scope=openid' -s | jq .auth_req_id -r
EOS
`
auth_req_id=`eval "${backchannelReq}"`
echo ${auth_req_id}
for i in {0..3}; do
sleep 3
tokenReq=`cat << EOS
curl http://localhost:8080/api/token -X POST \
--user ${clientId}:${clientSecret} \
-H 'Content-type: application/x-www-form-urlencoded' \
-d 'auth_req_id=${auth_req_id}' \
-d 'grant_type=urn:openid:params:grant-type:ciba' -s
EOS
`
token=`eval "${tokenReq}"`
error=`echo ${token} | jq 'select(.error_description==null)'`
echo ${token} | jq
if [ -n "$error" ]; then
break;
fi
done
$ ./ciba_request.sh
lrHy0QdUalqpL7K2MRMfV_uhCLuvolCk5hS70LEb7R8
{
"error_description": "[A200308] The end-user has not been authenticated yet.",
"error": "authorization_pending",
"error_uri": "https://www.authlete.com/documents/apis/result_codes#A200308"
}
{
"error_description": "[A200308] The end-user has not been authenticated yet.",
"error": "authorization_pending",
"error_uri": "https://www.authlete.com/documents/apis/result_codes#A200308"
}
//If you press Allow in the simulator here. ..
{
"access_token": "RexqI1mrrCpVI9fiYJWhxuJMSSOfD6j1ijNXs-cXOts",
"refresh_token": "x0CuGD-CPK1q2b8WzuU5WYBeCoIxdkBg5aaenLCeeWQ",
"scope": "openid",
"id_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdF9oYXNoIjoidVBRWVVnT1BmenVaQ1Jab0E1b21XUSIsInN1YiI6IjEwMDEiLCJhdWQiOiIyNDkzOTMxNjU5OTciLCJhdXRoX3RpbWUiOjE1NTQyNTc4NzksImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTU0MzQ0MjgxLCJpYXQiOjE1NTQyNTc4ODF9.1mdVZ2hub3GzwGNNxaL1HxlQHdIioSvLyp0UJfdMDog",
"token_type": "Bearer",
"expires_in": 86400
}
$
Sounds good. ..
This time, I tried to build a CIBA compatible authorization server (poll mode) using the Authlete service. Although it is far from understanding the whole feeling just by building the touch, I was able to easily set up the authorization server by using Authlete.
Thank you for your support.
Recommended Posts