OpenID Connect 1.0 OPとRPやRSを連携してみる

#はじめに
OpenID Connect 1.0のJavaによるOPサーバーのスクラッチ実装をApacheモジュールで実装されているmod_auth_openidcと連携してみます。

#前提
説明のためにFQDNはmyop.example.comとしています。
- CentOS7ベース
- Apache(443)とTomcat(8080)が動作していること
- ApacheにはSSLサーバ証明書が正しく設定されていること（重要！）

#OP側のインストール
OPサーバーのスクラッチ実装例(myop.war)をダウンロードして/usr/share/tomcat/webapps配下に配置します。
https://github.com/namikitakeo/myop

Tomcatを起動して動作確認します。
service tomcat start
curl http://myop.example.com:8080/myop/.well-known/openid-configuration

{"response_types_supported":["id_token","token","token id_token"],"scopes_supported":["openid","profile","email","address","phone"],"issuer":"https://myop.example.com/myop","authorization_endpoint":"https://myop.example.com/myop/authorize","jwks_uri":"https://myop.example.com/myop/jwk_uri","id_token_signing_alg_values_supported":["RS256"]}

curl http://myop.example.com:8080/myop/jwk_uri
{"keys":[{"kty":"RSA","kid":"public.key","use":"sig","alg":"RS256","n":"AJ56Fm5BN0rQqvRLUGhR6IBjNZWiXRpQ5FVFSgBizmQtD1wNGqjOeK0jKLtE-oTGXSbUTCkTzH1HUQcZwJJ79wGmhC04lPVUnQ0SwQl-K63mm0GgrTgZDHv55MOf_eB832Gu39iJ2QvjjGwNVgAbb3aU4V6f6KFTu6cZtKO9WHCWwbEV4VoSNJOFZyZUl-GoxC86o66PcckePzsjstjHaDtNU7zidJiKT0bZ0WtcQLbzxOY2e1KOLDCUkUmD3c-XSIREWVvpMNszNWQ9w6HkxUkCls71g_aumW7WlDCI8AkAcsJxh7nPZKJFBRMAeA2MqtbebEq3KUZVlax675R3Ouk","e":"AQAB"}]}

#RP側のインストール
RPMファイルをダウンロードします。
https://github.com/pingidentity/mod_auth_openidc/releases
https://dl.fedoraproject.org/pub/epel/7/x86_64/h/

RPMファイルをインストールします。
rpm -i mod_auth_openidc-1.8.8-1.el7.centos.x86_64.rpm hiredis-0.12.1-1.el7.x86_64.rpm

#OP側の設定
```
<Location /myop>
ProxyPass ajp://localhost:8009/myop
Order allow,deny
Allow from all
</Location>
```

#RP側の設定
```
OIDCProviderMetadataURL https://myop.example.com/myop/.well-known/openid-configuration
OIDCClientID myop
OIDCClientSecret password
OIDCRedirectURI https://myop.example.com/cgi-bin/redirect_uri
OIDCCryptoPassphrase ＜password＞
OIDCResponseType "token id_token"
OIDCScope "openid profile phone email address"
OIDCAuthRequestParams prompt=consent
# OIDCAuthRequestParams prompt=login%20consent
# OIDCAuthRequestParams prompt=login&login_hint=George

<Location /cgi-bin\>
AuthType openid-connect
Require valid-user
</Location>
```

#RS側の設定
```
OIDCOAuthIntrospectionEndpoint https://myop.example.com/myop/tokeninfo
OIDCOAuthIntrospectionEndpointMethod GET
OIDCOAuthIntrospectionTokenParamName access_token
OIDCOAuthRemoteUserClaim openid
# OIDCSSLValidateServer Off

<Location /myrs>
Authtype oauth20
Require claim scope:openid
# Require claim openid:george
# Require claim issued_to:myop
ProxyPass ajp://localhost:8009/myop
Order allow,deny
Allow from all
</Location>
```

#動作確認
テスト用CGI(landing)を用意して以下にアクセスします。/cgi-bin配下はmod_auth_openidcで保護されているのでOPにリダイレクトされます。george/costanzaでログインできれば成功です。
https://myop.example.com/cgi-bin/landing

```
#!/usr/bin/perl
print "Content-type: text/html; charset=UTF-8\n\n";
print "<html>";
print "<head>";
print "</head>";
print "<body>";
$val = $ENV{$var};
$val =~ s|\n|\\n|g;
$val =~ s|"|\\"|g;
print "Hello, ";
print "$ENV{\"OIDC_CLAIM_sub\"}<p>";
print "curl -k https://myop.example.com/myop/.well-known/openid-configuration<p>";
print "curl -k https://myop.example.com/myop/tokeninfo?access_token=$ENV{\"OIDC_access_token\"}<p>";
print "curl -k -H \"Authorization: Bearer $ENV{\"OIDC_access_token\"}\" https://myop.example.com/myrs/userinfo<p>";

print "<a href=\"https://myop.example.com/cgi-bin/redirect_uri?logout=https://myop.example.com/myop/logout\">logout</a>";
print "</body>";
print "</html>";
```

#最後に
わかりずらい部分がありましたら追記いたします。

ASP.NET Identityに対応しました。(2020/4/18)
https://qiita.com/namikitakeo/items/0a4355c741199e8c83ed