AngularでQR/バーコードを使用するInputコントロールを作る
12/1 修正しました。
はじめに
今回のお話は、下記バージョンでお送りします
AngularCLI : 7.0.4
↓みたいなコントロールを作成していきます。
テキストボックスがあり
フォーカスが当たった際に、ソフトウェアキーボードではなくQRを読み込むカメラが起動し
カメラでQRが読み込めた場合
フォーカスが当たっていたテキストボックスに、QRから読み取った値を投入する。
といった動作です。
QR/バーコード読み込み
以前の記事でQRコードを読み取るために、@zxing/ngx-scanner
を使用しました。
今回は、そのライブラリからForkされた、@innotec/ngx-scanner
を使用します。
npm install @innotec/ngx-scanner --save
@zxing/ngx-scanner
の@Inputにはformats
が追加されており、CODE39等のバーコードのFormatを指定することで
バーコードのデータも読み込むことができるようになります。
Formatの指定は、@zxing/library
の Enumで管理されている、BarcodeFormat
の配列を使用します。
Selectorはzxingのngx-scannerと同様なので、下記のようにFormatを指定する部分のみが変わる感じです
<zxing-scanner #scanner [formats]="[BarcodeFormat.QR_CODE, BarcodeFormat.CODE_39]"> </zxing-scanner>
ngx-scannerの使い方は、以前書いた記事を参考にしていただければと思います。
AngularでQRする - はまったりひらめいたり…とか…
Angular Material BottomSheet
画面下からにゅっと飛び出てくるコントロールを作るために
AngularMaterialのBottomSheetコンポーネントを使用しました。
準備
まずは、Materialを使用するために、お決まりの
ng add @angular/material
を行っておきます。
@NgModuleでBottomSheeetのモジュールMatBottomSheetModule
をインポートしておきます。
親コンポーネントからの使用
constructorでMatBottomSheetのDIを行うことで、BottomSheetの処理が使用可能になります。
親コンポーネントから、BottomSheetのOpen()
を実行すればBottomSheetが表示されます。
その際、BottomSheet内に表示するComponentを指定することが可能です。
≪MatBottomSheet≫.open(SheetBodyComponent);
この時BottomSheetに表示されるComponentは、表示されるタイミングでインスタンス化されるようなので
LazyLoadするComponentの時同様、NgModuleのEntryComponentに加えてあげる必要があるようです。
@NgModule({ ... entryComponents: [ SheetBodyComponent ], ... }) export class AppModule { }
サービスの注入
QR/バーコードが読み込まれたタイミングで、親コンポーネントがその結果を引っ掛けたいです
ただ、BottomSheet内のComponentは、EntryComponentなので、@Output
あたりで引っ掛けるのも難しそうです。
なのでDIするClassを作成し、その中のSubjectなプロパティを介して
BottomSheet内Componentと、親Componentでデータのやり取りを行う方法をとろうと思います。
親コンポーネント
// BottomSheetをOpen const res = ≪MatBottomSheet≫.open(SheetBodyComponent); ≪DI Class≫.≪Subjectプロパティ≫.subscribe(x => { // QR/バーコードがScan出来た場合 // InputElementに対して取得したQR結果を突っ込む // ElementRefを使用しInputコントロールを取得する const con = <HTMLInputElement>≪ElementRef≫.nativeElement.querySelector('input'); con.value = x; // BottomSheetを閉じる res.dismiss(); });
BottomSheet内コンポーネント
handleQrCodeResult(resultString: string) { // QRが読み込めた時の処理。サービスのSubjectプロパティに値を流す ≪DI Class≫.scanSuccess.next(resultString); }
スクリプト内で特に指定しない限り、BottomSheetはEscキーなり、BottomSheet外をClickするなりしないと閉じないので
値が読み込めた段階で、bottomsheetのdismiss()
を使用して用がすんだら閉じてあげるのが良いかと思います。
bottomsheetのafterDismissed().subscribe()
で、BottomSheetが閉じた時を引っ掛けれるので
BottomSheet閉じた際に何か処理をしたい場合は、そいつを使うと楽にいろいろできそうです。
これで、親ComponentとBottomSheetのComponentでデータのやり取りが可能になりました。
結果
冒頭のGifの通り、QR/バーコードを使用したInputコントロールが作成できました。
おわりに
ソフトウェアキーボードみたいな、フォーカスあてると下からニュッと入力インターフェースが出てくるコントロールを作りたいという思いでBottomSheetを使用しました。
今回はQR/バーコードの読み取りで使用しましたが
Canvasあたりを使用すれば、手書きの入力コントロールも、OSのインターフェースっぽく表現できるかもしれませんね。
今回作成したものは、下記リポジトリで管理しています。
サンプルで作ったもののごった煮ですがご容赦ください。
バーコードとQRの生成は下記のサイトを使用しました。
バーコード
QR
Azure DevOpsとBlob StorageでClickOnceアプリケーションのCI/CDできるか「雑に」試してみた
はじめに
れがしぃなWindowsFormsなプロジェクトをAzure DevOps(ADO)でCI/CDできるか「雑に」試してみました。
exeをどこかに吐き出すだけでは面白くないので
Azure Blob Storage上にClickOnceアプリケーションをデリバリして
Web Apps上のリンクからそのアプリケーションを使用する。
みたいな形で構成していこうと思います。
「できるかな?」程度なので、超雑な構成になっています。
証明書周りやCORS周りなんかは、もうちょっと検証が必要と思います。。。
最終的に↓な感じで動きます。
Windows Formsプロジェクト
まずはWindowsFormsプロジェクトの作成です。
といっても、アプリケーション自体はそこまで重要ではないので
WindowsFormsの画面を表示させるだけの機能のものです。
アプリケーションの発行する際にClickeOnceの署名等も行うよう設定しておきます。証明書はVisualStudioで作成されるテスト証明書をそのまま使用します。
ADO CI/CDパイプライン
VisualStudioBuildタスク
ADOパイプラインのVisualStudioBuildタスクはデフォルトで、publishしてくれないので、タスクの内容を少しいじります
MSBuild:Arguments
に /target:publish
を指定するだけです。
PowerShellタスク
WinFormsのClickOnceで証明書を使用しているため、Buildを行う際にはマシンの証明書ストアに証明書がインストールされている必要があります。
PowerShellタスクを使用して、ビルドマシンに証明書をインストールしてあげます。
証明書ファイルはめっちゃ雑ですが
ソリューションに加えられたpfxファイルをADOにあげちゃってます
$pfxpath = 'pfxファイル' $password = '証明書パスワード' Add-Type -AssemblyName System.Security $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import($pfxpath, $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet") $store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", CurrentUser $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite") $store.Add($cert) $store.Close()
Azure File Copyタスク
ClickOnceアプリケーションは bin
の中に生成されるので
binディレクトリの中のファイルをFile CopyタスクでBlobストレージにアップロードします。
基本的にAzureのBlob Storageとリンクされます。なので迷わず設定できます。
結果
指定したコンテナに.application
他生成されたファイルがコピーされました。
Blob Storage他の雑な設定変更
ここからかなり雑です。
アセンブリの設定変更
オレオレ以前な証明書を使用しているので、*.application
にアクセスしてもファイルの起動が行なえません。
Let'sやらOpenSSLを使用してあげれば回避できるとは思うのですが
今回は、コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Security\TrustManager\PromptingLevel
の設定をすべてenabled
に変更して回避しました。
BlobStorageのアクセスポリシー変更
当初、SASトークン付きのURLでapplication
ファイルにアクセスしていたのですが
アプリケーションのインストールを行う際、当然 .manifest
などの他のファイルもBlobStorage経由で取得しようとします。
しかし、アプリケーションのインストール時は、インストーラでSASトークン付きのURLに対してアクセスしてくれないため、404が発生し、インストール時にエラーとなってしまいます。
BlobStorageでCORSを設定してみたのですが、そもそもローカルにインストールされたインストーラからのアクセスなので、CORSも効かない…
ので、アクセスポリシーをユッルユルに設定しアクセスできるようにしました。
雑に設定した結果
.application
へのLinkを貼っただけのHtmlをアップし動作させてみました。
結果は記事の冒頭に貼った通りの結果でClickOnceのおなじみの動きとなっています。
おわりに
BlobStorageにアップしたClickOnceアプリケーションは使用できそうです。
ただ、さすがにAnonymousで制限なくアクセス可能。という状態を避けたい場合はもうすこし考慮が必要かもしれません。
アプリケーションへのエントリがWebからのみ。ということであれば
Web画面のCI/CDパイプラインでアプリケーションを混入した状態で、WebAppsにデプロイしちゃったほうが良いかもしれないですね。
Azure DevOpsでAngularのJestテストのCIをまわせるか試してみた
はじめに
Angularは下記Verisonでお届けします。
- AngularCli:7.0.3
先日の、bitbank LT NightでみたJestがとても良い感じで使ってみたくなったので
現在使用しているCI環境のAzure DevOps(以降ADOと呼びます)で使用できるか確認してみました。
Azure DevOps
お仕事で使用していますが、Publicなプロジェクトでも使用できます。
Publicなプロジェクトの場合(厳密にはOSSプロジェクトとのことですが)、ビルド時間を無制限に回せるようです。
Azure DevOps のご紹介 – Cloud and Server Product Japan Blog
WebからWindowsアプリ、Andorid/iOSもビルド可能となかなか最強味が強い環境です。
OneDriveみたいに、無制限→制限!のような未来を辿らなければいいと願っています。
Angularの下準備
まずはAngularでJestのテストができるようにします。
下記を参考にしました。
ひとまず、ng new
したプレーンな環境から作成しました。
上記の記事に記載されている通りの変更を行います。
- パッケージのインストール
- jestテストするためのスクリプトをpackage.jsonに追加
- jestの設定ファイルの
jest.ts
をsrc
ディレクトリに配置 tsconfig.spec.json
の変更
あっさりとJestでテストが可能なところまで持っていくことができました。
結果レポートの出力
前の記事の内容の通り、ADOはjUnitのXMLを食わせばレポート出力してくれるので
jestからjUnitのレポートを出力できるようにします。
パッケージのインストール
jUnit出力に使用するパッケージをインストールします。
npm install --save-dev jest-junit
レポート出力の設定
Jestコマンドでレポート出力されるよう、package.json
の設定を変更していきます。
"jest": { ... "reporters": [ "default", "jest-junit" ] }
default
が先程行ったコマンドラインで表示されるテスト
jest-junit
がjUnitのXML形式で出力されるテストの設定です。
今回は、jest-junitのオプションに特に指定をしないので
rootディレクトリに「junit.xml」という名前で結果ファイルが出力されます。
テストコマンドも少し変更します。
今回の変更でテストレポートが複数パターンになったので
テスト内容によってどっちのレポートを使用するか指定しておきます。
package.jsonのスクリプトを下記のように変更しました。
"scripts": { ... "test": "jest --reporters=default", "test:ci": "jest --reporters=jest-junit", ... }
スクリプトコマンドの通り、npm run test:ci
でXMLが出力されます。
CIの構築
今回はGitHubリポジトリから、ソースを引っ張ってきてADOでCIします。
せっかくなので、Public環境のADOを使用しようと思います。
ADOの設定
GitHubのリポジトリからソースを引っ張ってくるパイプラインを作ります。
NewPipelineでGitHubを選択するだけ。簡単ですね。
テンプレートはどうせあとからいじるので、Blankなものを選択します
パイプラインを作成したら、ソースのリポジトリのルートディレクトリに
パイプラインの設定ファイルazure-pipelines.yml
が追加されています。
パイプラインをYamlで作成
パイプラインができたら、Buildの設定を作っていきます。
ADOのCIは、デフォルトではルートディレクトリにある、azure-pipelines.yml
の設定を参照し、CIのパイプラインが実行されます。
今回は、下記の感じで構成しました。
ルートディレクトリ配下にAngularのプロジェクトファイルがあるのでちと変則的ですが…
resources: - repo: self queue: name: Hosted VS2017 demands: npm npmインストール steps: - task: Npm@1 displayName: 'npm install' inputs: workingDir: AngularWithJest verbose: false npmテスト実行。CI用のテストを実行する。 - task: Npm@1 displayName: 'npm run test' inputs: command: custom workingDir: AngularWithJest verbose: false customCommand: 'run test:ci' 出力されたXMLファイルをテスト結果として取得する - task: PublishTestResults@2 displayName: 'Publish Test Results **/junit.xml' inputs: testResultsFiles: '**/junit.xml' condition: always() buildする。 - task: Npm@1 displayName: 'npm build' inputs: command: custom workingDir: AngularWithJest verbose: false customCommand: 'run prod-build'
ADOのyamlについては、下記サイトが参考になります。
YAML schema - Azure Pipelines | Microsoft Docs
結果
あえて失敗するテストを混入した状態でCIを回しました。
下記の通りきちんとエラーの内容が出力されています。
エラーを修正し、再度CIを回すと、きちんと反映されていることが確認できます
最後に
そもそもJest使用できるかな?程度のものなので、まだまだ検証することは多いかなと思います。
Jestは全然触っていないので、これからいろいろ覚えたい感じです。
さて、今回作成したソースと環境は下記になります。
Publicな環境でAzure DevOpsプロジェクト作成したのでテスト結果も見る事が可能です。
Azure DevOps: angularxstudy-ci
(僕の失敗の軌跡も見ることができるので少し恥ずいですが…)
AngularでQRする
はじめに
この記事は、下記のVersionでお送りします。
- Angular CLI : 7.0.3
どんな風に動作する?
こんな感じです。ちょっと見えづらいですが
一番下部で数字をカウントしているのがQRコードの読み取り結果です。
QRは2秒毎に0からカウントアップしていき、秒数をQRコードに変換しています。
QRコードの読み取りは早い方ではないでしょうか?
AngularでQRコードを読む
使用するライブラリ
QRコードを読むライブラリとしては、ネイティブではZxingが有名だと思います。
Angular用のZxingライブラリのngx-scanner
が開発されいますので
今回はそれを使用しようと思います。
注意
今、iOS12でQRを読み込んでくれないバグが存在するようです。
が、上のGifの通り動作していますね。
Angular6 + ngx-scannerの食い合わせが悪いのかもしれません。
(今回、Angularはv7を使いました)
次のリリースで解決するとアナウンスはされていますが、使用する際は注意が必要です。
IOS12 iphone/ipad · Issue #140 · zxing-js/ngx-scanner · GitHub
ngx-scannerの事始め
QRコードの読み取り機能自体は、非常に簡単に使用することができます。
npm i @zxing/ngx-scanner --save
して
Angularでは恒例の、ngModuleでインストールしたライブラリを読み込んでやってから
Htmlテンプレートで<zxing-scanner></zxing-scanner>
だけで使用できます。
ただし、Webカメラを使用する必要があるため
それを使用できるようにするまでで、ひと手間必要です。
デバイスで使用できるカメラを取得する
zxing-scanner
コンポーネントで使用できるカメラを探してくれます。
結果は、コンポーネントの camerasFound
ファンクションに
Obserbableで返却されます。
<zxingcomponent>.camerasFound.subscrive( devices => { hogehoge } )
で
引っ掛けて使用できるカメラデバイスを把握し
使用するカメラを選択する必要があります。
使用するカメラをコンポーネントの device
プロパティに食わせて
使用できる状態にする必要があります。
簡単に書くと下記な感じでしょうか?
<zxingcomponent>.camerasFound.subscribe((devices: MediaDeviceInfo[]) => { <zxingcomponent>.device = <zxingcomponent>.getDeviceById(devices["index?"].deviceId); });
ただ、カメラデバイスを見つけた時のObservableのみでdeviceを設定すると
好きなカメラに変更できないので
<zxingcomponent>.device
に食わせる値は変数にして
取得した devices
を保持して変更できるようにしておいたほうが良いです。
プロパティに使用するカメラの情報を食わせると
カメラを使用してQRを読み込んでくれるようになります。簡単ですね。
読み取り結果を取得する
Scanした結果は、Zxingコンポーネントの 'scanSuccess' ファンクションに
Observableで返却されます。
<zxingcomponent>.scanSuccess().subscribe(result: string => { })
で
結果を引っ掛けるだけでOKです。
camerasFound
も scanSuccess
もEventEmitterで結果が返却されているようなので
<zxing-scanner (camerasFound)="hogehoge()" (scanSuccess)="fugafuga()" >...
としてもいいと思います。これも非常に簡単ですね。
AngularでQRコードを生成する
使用するライブラリ
ngx-scannerで紹介されていた ngx-kjua
を使用します。
ngx-kjuaことはじめ
npm install ngx-kjua --save
して、同様にngModuleでライブラリを読み込んでから
Htmlテンプレートで<ngx-kjua></ngx-kjua>
で使用できます。
カメラ等のデバイスを使用しないため、特に前段階の準備をすることなく使用できます。
QRコードにしたい文字列かimageをコンポーネントのプロパティに下の感じで指定するだけで
QRコードが生成されます。超楽です。
<ngx-kjua [text]="'qrにしたい文字列'"></ngx-kjua>
さいごに
QRコードを用いたアプリケーションを比較的容易に作成することができます。
いろいろと利用できる範囲も広いですし、楽しい使い方もできると思います。
今回作成したWebApplicationは、下記レポジトリで管理してます。
Angularの勉強で使用したソースのごった煮ですが、ご容赦ください。
VSTSでAngularのユニットテスト
はじめに
今回の記事の構成は下記のとおりです。
- AngularCLI : 7.0.3
- Angular : 7.0.1
Azure DevOpsの略し方が未だにつかめていないので
VSTSの名称でお送りいたします。(ADops…?)
今回のゴール
AngularのUnitTestをVSTSで実施し
結果をVSTSのテストレポートで確認するところまでを目指します。
Angularのプロジェクトの作成からテストコードの作成までは割愛します。
ただ、ネット上に転がっている文献では
PhamtomJSを使用しているものが多いのですが
AzureDevOps(VSTS)でHeadlessChromeが使用できるようになっていることもあり
CIテストに必要な工程はだいぶ減っている印象です
VSTSのReporter出力の準備
VSTSのレポート出力用に、JUnitReporterをインストールします。
また、HeadlessChromeでテストを実行するので、Pupetterもインストールします。
npm i karma-junit-reporter --save-dev
npm i puppeteer --save-dev
karmaでHeadlessChromeを使用する設定を追加していきます。
- karma.conf.js
process.env.CHROME_BIN = require('puppeteer').executablePath();
plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('karma-junit-reporter'), // 追加 require('@angular-devkit/build-angular/plugins/karma') ],
browsers: ['Chrome', 'ChromeHeadless'], //ChromeHeadlessを追加
karmaのテストレポートでjunitを使用するよう設定追加します。
- karma.conf.js
reporters: ['progress', 'kjhtml', 'junit'], // 'jUnitを追加' junitReporter: { // 出力ディレクトリ outputDir: require('path').join(__dirname, '../reports'), // 出力ファイル名 outputFile: 'test-results.xml', suite: '', useBrowserName: false },
Angularのテスト\スクリプト作成
CI環境下で実行するため、HeadlessChromeで一回のみテストを実行するコマンドです。
- package.json
"citest": "ng test --watch=false --no-progress --browsers=ChromeHeadless",
VSTSのCIパイプラインを構築
VSTSでAngularのテストを行うよう、パイプラインを構築していきます。
1.Angular-cliをインストール
ng
コマンドを使用するために@angular/cliをインストールしておきます。
2.npm install を実行
3.組んだCI用のテストを実行する
4.テストが失敗していた場合はレポートを出力する
5.テストが成功していた場合はビルドする
テストで失敗した場合
AngularのTypeScript側で失敗したエラーが
VSTSのレポートから確認できるようになりました。
最後に
少し前まではHeadlessChromeが使えなかったので
PhamtomJSをインストールしたり、設定を追加していたりしたのですが
だいぶ楽にCIの自動テストの構成を作ることができるようになりました。
ただ、npm installをしている関係で、一回のサイクルに5分位かかってしまうので
ビルド時間に制限のあるPrivateリポジトリでのCIについては
乱発しないように注意が必要かもしれません。
Azure WebAppsのHybridConnectionでドハマりしたとき試したこと
Azure WebAppsのHybridConnectionとは、Azure上のVPNなどの閉域網を構成しなくても
社内閉域網サーバー内のデータにアクセスできるツールです。
エンプラ系の課題にリーチしそうですね。
こと、Cloud移行したいんだけど一気には無理・・・なんて要求に対応しやすいです。
WepAppsとオンプレサーバーがつながらない
HybridConnectionはハイブリッド接続マネージャーという
クライアントソフトウェアを介して通信が行われるのですが
基本的にはインストールして、接続するエンドポイントを指定するだけの簡単なものです。
詳細は 過去記事をどうぞ。
しかし、ある環境で試したところ、接続できずに四苦八苦しました。
そのときに試したり確認した色々なことを書いていこうと思います。
0.まずはOSの確認を
HybridConnectionはWebSocketを使用して通信を行っているため
WindowsServerであれば2012以降からしか対応していません。
1.接続設定の確認
HybridConncetionの設定の際に、PCの名称を指定するフィールドがあります。
ここの部分で名称を間違えたり、IPアドレスを指定したりすると繋がりません。
正しい設定になっているかどうか確認します。
2.ファイアウォールの確認
HybridConnectionは送信ポート443を使用して通信します。
ハイブリッド接続マネージャでエンドポイントを設定する際は
受信・送信ともにポート443を開放していないと設定できないですが
設定後は、送信ポートだけの開放でも問題なく動作するようです。
OSのファイアウォールで送信ポート443がブロックされているようであれば
開放してあげましょう。
※もちろん443を潰すということはセキュリティ的に重要なPCの可能性が高いので事前確認は忘れずに!
3.サービスが可動しているか確認
前述の通り、HybridConnectionはハイブリッド接続マネージャを介して通信が行われるので
常駐プロセスが立っているはずです。これが停止されていないか確認します。
4.インターネット接続の確認
それでもつながらない場合、そもそもインターネットにつながっている状態か確認します。
状況により下記の通り対応が分岐されます。
4.1 つながらない
ルーターの設定でブロックされている可能性があるので、ルーターの設定を確認します。
4.2 つながる
Proxyサーバーを介して通信が行われている可能性があるので確認します。
4.2.1 Proxy設定を確認
インターネットオプションから、Proxyを介した接続設定となっているか確認を行います。
4.2.2 ハイブリッド接続の設定を変更
Proxyを介して通信を行う設定となっていた場合
ハイブリッド接続マネージャーも、Proxyを介して通信をするよう変更します。
ハイブリッド接続マネージャーの実行ファイルと、同じディレクトリにある
Microsoft.HybridConnectionManager.Listener.exe.config
ファイルの中身を変更します。
設定に下記内容を付け加えます。
<system.net> <defaultProxy> <proxy usesystemdefault="true" proxyaddress="http://hogehoge.proxyserver:1111" /> </defaultProxy> </system.net>
proxyaddress
には先程インターネットオプションで確認したProxy設定を記述します。
自分はひとまずこれで接続することができました。
最後に
HybridConnectionは、大雑把に言ってしまえばSSLでデータをやり取りしているだけなので
ハイブリッド接続マネージャーを入れたサーバーで、インターネットにつながるのであれば
netstat
とか Test-NetConnection
を使用して
通常のネットブラウズで使用されている経路やポートを抑えるのが、解決への早道となりそうです。
AngularとAzureAD認証でログイン機構を簡単に実現したい
最初に
今回使用した環境は下記の通りです。
- @angular/cli : 6.0.8
- @angular : 6.0.7
AzureAD認証を支援するJSライブラリ
AzureActiveDirectory認証を支援するJSライブラリとして
MicrosoftからADALというJSライブラリが提供されています。
マルチテナント型のAzureADB2CはMSALと呼ばれるライブラリを使用するようです。
ADALのAngularラッパーを取得
Angular使いなので、Angularでadal.jsを使おうと思います。
adal.js自体はnpmでパッケージ提供されていないようです。。。
Angularで使用できるラッパーは提供されているようなのでそいつを使用していきます。
npm install adal-angular4 --save
Angular4と書かれていますが6も対応されています。
Angular6対応版もありますが、Deprecateして4に吸収されているようです。
(名前、ngx~みたいな形のほうがわかりやすいですよね…)
ServiceをImportしてProvide
まずはInjection宣言されている、AdalSeviceを app.module.ts
でProvideします。
import { AdalService } from 'adal-angular4'; ・・・ providers: [ AdalService ],
ADの情報を設定
AdalService.init()
に使用するADの情報を食わせる必要があります。
Sampleで指定されているのではTenantとClientIDです。
TenantはADで使用されているドメイン。
ClientIDはADに登録されたアプリケーションのApplicationIDを指定します。
handleWindowCallbackでログイン状態の収集
先程ProvideしたAdalServiceを介して認証情報のやり取りを行います。
サービス内の handleWindowCallback()
を使用し
サインインされているか~ですとか、Tokenの情報~ですとか
そういった情報が収集されているようです。
ログインされているかの情報は
this._adalService.userInfo.authenticated
で確認できるので
ログインされているかを確認し
ログインされていないようであればログインするようにしてみます。
constructor( private _adalService: AdalService, ) { } ・・・ ngOnInit() { this._adalService.handleWindowCallback(); if (!this._adalService.userInfo.authenticated) { this._adalService.login(); } }
このようにしておくと、Componentの初期化と同時に
AD未ログイン状態だった場合は
AzureActiveDirectoryの認証画面にリダイレクトされます。
AdalGuardでComponentの遷移Guard
AdalGuardは、Angularの CanActivate
と
上記の userInfo.authenticated
を使用して
AD未ログインユーザーのRoutingの制限を行うSampleという認識です。
adal-angular4/adal.guard.ts at master · benbaran/adal-angular4 · GitHub
認証されていないユーザーへの移動制限をかけたい場合は
routerの設定のときにAdalGuardを指定するだけでOKといった塩梅です。
ここで認証されていない場合は強制的にリダイレクトかけたりなんだりしたいと思うので
基本的にAdalGuardをそのまま使用することはないかなぁ?と思っています。
今回はLoginComponentからDashboardComponentへの遷移の設定を作ってみます。
const routes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'dashboard', component: DashBoardComponent, canActivate: [AdalGuard] }, { path: '', component: LoginComponent }, ];
今回はAdalGuardをそのまま使用します。
認証がすでに済んでいるものはURL指定で直接遷移できていますが
認証が済んでいないほうはRouterで遷移ができずに
何も表示されていない状態になっています。
AD認証のAuthがかかったASP.net WebAPIへのアクセス
adal-angular4が提供する AdalInterceptor
が
AngularのHTTP_INTERCEPTORを使用して、ヘッダに認証情報を付与します。
adal-angular4/adal.interceptor.ts at master · benbaran/adal-angular4 · GitHub
なので、app.module.ts
でInterceptorのInjectionを行えばいい感じです。
providers: [ AdalService, { provide: HTTP_INTERCEPTORS, useClass: AdalInterceptor, multi: true } ],
WebAPIを作る
WebAPIはASP.net CoreでAD認証付きのAPIがテンプレートから作れるので
それでサクッと作ってしまいます。
F5実行して動作を見てみます。
アクセスするAPIはデフォルトで存在する /api/values
のGetにアクセスしてみます。
まずは、RestletClientから、Token情報を付与しない状態でアクセスしてみます。
401エラーが返却されました。認証は問題なく動作しているようです。
AdalInterceptorを通してからアクセスした場合を見てみます。
横着してConsole出力で済ませています。
Networkからも、HeaderのAuthorizationにTokenが使用されているのが確認できます。
先程失敗したRestletClientで、使用されたTokenを使ってみます。
通りました。正しいTokenのようです。
まとめ
JSでのActiveDirectory認証はADALを使用します。
今回はAngularを使用しましたがVue用等
各Frameworkのものも用意されているようです。
ログイン画面やアカウント管理は非常に重要で気も使う部分です。
簡易な要望でADを使用している人や会社が対象であれば
AD認証で認証ロジックを丸投げしてしまうのもありですよね。