トークンを使った認証・承認
NSO 4.6 より、NSOに対する認証の際、トークンを使用できるようになりました。
現在のところ、RESTCONFで使用が可能です。
一度目の認証では、これまで同様、BASIC認証を行い、その際の返答に、Tokenが返るように設定します。
二度目以降の認証では、そのTokenを使用し、実際のユーザ名・パスワードが何度も送信する必要がなくなります。
認証、及びトークンの発行
NSOでは、従来からExternal Authenticationをサポートしており、トークン発行にはこれを使用します。
External Authenticationでは、NSOの管理者が作成したスクリプトなどを実行し、NSOが渡すログイン情報を元に、認証可、認証不可の判断を得ることで実現しています。
ncs.conf
<aaa>
<auth-order>external-authentication local-authentication</auth-order>
<external-authentication>
<enabled>true</enabled>
<executable>./auth.pl</executable>
<use-base64>false</use-base64>
</external-authentication>
</aaa>
上記設定の上、auth.pl を以下のように作成します。
この例では、Perl スクリプトとなっていますが、標準入力からユーザ名、パスワードを読み取り、結果を標準出力へ出すことができるのであれば、Python やシェルスクリプト、また通常の実行ファイル等で構いません。
詳細は、Administration Guide -> The AAA infrastructure -> Authentication -> External authentication をご確認ください。
auth.pl
#!/usr/bin/perl
$line = <>;
$line =~ tr/[]//d;
@input = split(/;/, $line);
$username = $input[0];
$password = $input[1];
if ($username eq 'cisco' && $password eq 'cisco'){
print "accept admin 500 10 20 /";
}else{
print "reject u:$username:, p:$password:";
}
この例では、ユーザ名として "cisco"、パスワードとして "cisco" が入力された場合のみ、認証可としています。
それ以外の場合は、全て認証不可です。
トークンを使用する場合は、以下のようにトークンをNSOへ渡すようにしてください。
#!/usr/bin/perl
$line = <>;
$line =~ tr/[]//d;
@input = split(/;/, $line);
$username = $input[0];
$password = $input[1];
if ($username eq 'cisco' && $password eq 'cisco'){
print "accept_token admin 500 10 20 / admintoken\n"
}else{
print "reject u:$username:, p:$password:";
}
この例では、必ず "admintoken" というトークンを返却しています。
実際の運用では当然ながら、乱数を使った文字列を作成するなど、そのアルゴリズムを決定し、別のセッションでは別のトークンが生成されるようにします。この後記述するValidation では、そのアルゴリズムを使用し、入力されたトークンの正当性を確認する必要があります。
トークンを使用した認証
External Authenticationで認証した際に発行したトークンを使用して、二度目以降の認証を行うことが出来ます。
使用するためには、ncs.conf に以下の設定をしてください。
ncs.conf
<aaa>
<validation-order>external-validation</validation-order>
<external-validation>
<enabled>true</enabled>
<executable>./validate.pl</executable>
<use-base64>false</use-base64>
</external-validation>
</aaa>
validate.pl
#!/usr/bin/perl
$line = <>;
$line =~ tr/[]//d;
@input = split(/;/, $line);
$token = $input[0];
if ($token eq 'admintoken'){
print "accept admin 500 10 20 / admin\n"
}else{
print "reject invalid token";
}
ユーザがトークン認証を使用して、"admintoken" を認証情報として送信した場合、validation.plはそれを標準入力で以下のように受信します。
"[admintoken;]\n"
validation.pl は、その文字列からトークンを取り出し、正しいトークンかどうかを確認します。
実際にはトークン情報から、そのユーザ名や認証情報が確認できるようになっている必要があります。
External Authentication でトークンを作成する際、トークンをメモリやデータベースに保存する必要があるかもしれません。
トークン文字列自体にそれら情報を埋め込み、不可読状態にして使用するというのも、一つの方法でしょう。
この例では、"admintoken" はユーザ "admin"であるという情報が静的にvalidation.pl に記述されており、"admintoken" を使用して認証できるようになっています。
RESTCONF サーバの設定
ncs.conf には以下のような設定が必要です。
Tokenの送受信に、HTTP Header を使用する場合は x-auth-token をtrue に設定します。
Cookie で送受信をする場合は、token-cookie を設定します。
下記のように、両方を使用することも可能です。
<restconf>
<enabled>true</enabled>
<token-response>
<x-auth-token>true</x-auth-token>
<token-cookie>
<name>X-JWT-ACCESS-TOKEN</name>
<directives>path=/; Expires=Tue, 19 Jan 2038 GMT;</directives>
</token-cookie>
</token-response>
</restconf>
認証実施例
初回認証の際には、ユーザ名パスワードを BASIC 認証で送信します。
現在の設定では、HTTP header と Cookie の両方に、ユーザ名 cisco パスワード cisco で認証された際のトークン admintoken が静的に返されます。
$ curl -iu cisco:cisco http://localhost:8080/restconf
HTTP/1.1 200 OK
Server:
Date: Sun, 28 Oct 2018 17:15:01 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 157
Content-Type: application/yang-data+xml
Set-Cookie: X-JWT-ACCESS-TOKEN=admintoken; path=/; Expires=Tue, 19 Jan 2038 GMT;
Vary: Accept-Encoding
X-Auth-Token: admintoken
Pragma: no-cache
<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<data/>
<operations/>
<yang-library-version>2016-06-21</yang-library-version>
</restconf>
$
二度目以降の認証では、トークンを使用することができます。
この例では、admintoken は常に使用可能ですが、通常の実装では、認証後にそのトークンを有効とし、規定の期限を設けることが一般的です。
Header を使用して認証する
$ curl -i -H "X-Auth-Token: admintoken" http://localhost:8080/restconf
HTTP/1.1 200 OK
Server:
Date: Sun, 28 Oct 2018 17:19:59 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 157
Content-Type: application/yang-data+xml
Vary: Accept-Encoding
Pragma: no-cache
<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<data/>
<operations/>
<yang-library-version>2016-06-21</yang-library-version>
</restconf>
$
Cookie を使用して認証する
$ curl -i --cookie "X-JWT-ACCESS-TOKEN=admintoken" http://localhost:8080/restconf
HTTP/1.1 200 OK
Server:
Date: Sun, 28 Oct 2018 17:21:56 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 157
Content-Type: application/yang-data+xml
Vary: Accept-Encoding
Pragma: no-cache
<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<data/>
<operations/>
<yang-library-version>2016-06-21</yang-library-version>
</restconf>
$