概要

Keycloak の認証時にCROSエラーが起きるっていう話を聞いたのでテストしてみました

参考

https://keycloak.discourse.group/t/access-control-allow-origin-header-missing/328/20

環境構築

Keycloak起動

dockerを使ってKeycloakの最新版を起動します

1
2
3
4
docker run -dP \
    -e KEYCLOAK_USER=admin \
    -e KEYCLOAK_PASSWORD=admin \
    --name keycloak-test jboss/keycloak

dnsmask

CORSのテストをするため、起動したKeycloakへ .hoge.fuga で名前解決できるようdnsmaskコンテ名も同時に起動します

ブラウザなどのproxy設定に localhost:8888 を登録する事で localhostコンテナへ .hoge.fuga:port でアクセスできるようになります

1
2
3
4
docker run -d -p 8888:8888  \
    -e DISCOVERY=$(ifconfig en0 | awk '{print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}") \
    -e DOMAIN=hoge.fuga \
    --name dnsmasq moremagic/ubuntu-dnsmasq

テスト

keycloak コンテナの8080が55003でリッスンされてたとして 以下のコマンドどれでもアクセスが可能となります

1
2
3
curl --proxy localhost:8888 http://hoge.fuga:55003
curl --proxy localhost:8888 http://aaa.hoge.fuga:55003
curl --proxy localhost:8888 http://bbb.hoge.fuga:55003

テスト

とりあえずadmin-cliのトークン取得エンドポイントに対するリクエストでCORSがうまく動くかみてみることにしました

curl によるトークンの取得

まずAPIのエンドポイントが想定通り動くかテストします

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
URL="http://hoge.fuga:55005/auth/realms/master/protocol/openid-connect/token" 
KC_USER=admin
KC_PASS=admin
curl -vvv -s -k \
        --proxy localhost:8888 \
        -d "client_id=admin-cli" \
        -d "username=${KC_USER}" \
        -d "password=${KC_PASS}" \
        -d "totp=$input" \
        -d "grant_type=password" \
        "${URL}" \
        | jq -r '.["access_token"]'

結果、APIは正しく動作し、CORS の制限はかからないため問題なくトークンが取得できる



js によるトークン取得

chromeでkeycloak にアクセスする ex: aaa.hoge.fuga:55005

その後、Chromeの検証ツールを同じタブで開き、Consoleから以下を実行する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
let url = "http://bbb.hoge.fuga:55005/auth/realms/master/protocol/openid-connect/token"
let obj = {
  client_id: "admin-cli",
  username: "admin",
  password: "admin",
  grant_type: "password"
};
let method = "POST";
let body = Object.keys(obj).map((key)=>key+"="+encodeURIComponent(obj[key])).join("&");
let headers = {
  mode: 'cors',
  'Accept': '*/*',
  'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
};
fetch(url, {method, headers, body}).then((res)=> res.json()).then(console.log).catch(console.error);

結果、aaa.hoge.fuga から bbb.hoge.fuga へリクエストを送っているため cors errorとなる なお、aaa.hoge.fuga にリクエストを送った場合はCORSエラーにはならずレスポンスが返ってくることを確認している

Keycloak設定を見直す

以下を設定してみました https://huongdanjava.com/configure-web-origin-in-keycloak.html

1
2
3
4
*
hoge.fuga:55005
bbb.hoge.fuga:55055
http://bbb.hoge.fuga:55005

結論

keycloak の WebOrigin を設定してみたりもしたが結果が変わらず。 現時点(14.0.0)で Keycloak側のCORS対応にバグがあるような気がします