先日は普通のWebアプリでAzure AD B2Cを使うチュートリアルをやってみました。
今回は別のチュートリアルで、「Webアプリ」+「Web API」の構成のものを試した時のメモです。
この構成のポイントは、
・WebアプリはAzure AD B2Cを使って認証しトークンをもらう
・Web APIはそのトークンを使って認証を行う
という連動が行われていることです。
WebアプリはOAuth 2.0の仕組みでAzure ADにリダイレクトして認証を行いトークンをもらい、 Web API側ではそのトークンをBearerとして受け取り、それを元に認証を行います。
あらかじめ、WebアプリのAzure ADアプリケーションと、Web APIのAzure ADアプリケーションの2つを作成して、Webアプリ側のアプリケーションからWeb API側のscopeを利用可能なように設定しておきます。
この方式は、パブリックなWebAPIにはあまり向かず、例としては社内にWebアプリとWeb APIがあって、複数のWebアプリから共通機能を持ったWeb API(たとえば課金管理専用のAPI)を呼び出す、というシナリオが考えられます。
Webアプリ側は前回のチュートリアルとだいたい同じなので、Web API側のコードを見てみましょう。
まず、使っているパッケージで重要なものが、passportとpassport-azure-adです。
passportは認証を扱うexpressのミドルウエアで、passport-azure-adはpassportが認証方法として用いるStrategyになります。
// BearerStoragegyをインポート const BearerStrategy = require('passport-azure-ad').BearerStrategy; // 認証先のAAD B2Cサーバの情報 const options = { identityMetadata: `https://${config.credentials.tenantName}.b2clogin.com/${config.credentials.tenantName}.onmicrosoft.com/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`, clientID: config.credentials.clientID, audience: config.credentials.clientID, policyName: config.policies.policyName, isB2C: config.settings.isB2C, validateIssuer: config.settings.validateIssuer, loggingLevel: config.settings.loggingLevel, passReqToCallback: config.settings.passReqToCallback } // bearerStoragegyをインスタンス化 const bearerStrategy = new BearerStrategy(options, (token, done) => { // Send user info using the second argument done(null, { }, token); } ); const app = express(); // ミドルウエアを指定 app.use(passport.initialize()); // Stragegyを指定 passport.use(bearerStrategy);
この設定でexpressが起動した後、Web APIが呼び出された時のコードです
app.get('/hello', passport.authenticate('oauth-bearer', {session: false}), (req, res) => { console.log('Validated claims: ', req.authInfo); // Service relies on the name claim. res.status(200).json({'name': req.authInfo['name']}); } );
passport.authenticateで設定したStrategyで認証が行われると、reqにauthInfoというプロパティが生えてくるので、そこに認証されたユーザーの情報が格納されています。