-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETAndSSRS
- 戻る(SSRS)
ReportViewer を使用して連携可能。
- ReportViewer Web サーバーおよび Windows フォーム コントロール
https://learn.microsoft.com/ja-jp/sql/reporting-services/application-integration/integrating-reporting-services-using-reportviewer-controls-get-started
補足(連携方式は 3 つある): 原文は ReportViewer だけを挙げているが、
選択肢を整理しておくと設計しやすい。
方式 内容 認証の扱い ReportViewer コントロール アプリに埋め込む。本ページの主題 アプリが SSRS へ認証する(本ページの論点) URL アクセス iframe/ リンクでレポート マネージャーへ飛ばす利用者のブラウザが直接認証する Web サービス(SOAP / REST) PDF/Excel をバイト列で取得し、アプリが返す アプリが認証。画面を持たない 【ReportViewer】 ブラウザ → ASP.NET アプリ → SSRS ↑ ここの認証が課題(本ページ) 【URL アクセス】 ブラウザ → SSRS(直接) ↑ 利用者の Windows 認証がそのまま効く ↑ ただし Forms 認証のアプリとは繋がらない 【Web サービス】 ブラウザ → ASP.NET アプリ → SSRS(REST で PDF を取得) → アプリが PDF をそのまま返す移行メモ(ReportViewer の現況): ReportViewer は
.NET Framework専用であり、
ASP.NET Core 版は提供されていない
(帳票出力)。【.NET(Core 系)へ移行する場合の選択肢】 ① SSRS の【REST API】を叩いて PDF/Excel を取得し、アプリが返す ★ ② iframe で SSRS のレポートを埋め込む ③ Power BI Embedded に寄せる ④ 帳票基盤自体を置き換える([帳票出力] 参照)// ① SSRS の REST API(SQL Server 2017 以降)で PDF を取得する var url = $"{ssrsUrl}/api/v2.0/reports(path='/Sales/Monthly')/Export/pdf"; using var client = new HttpClient(new HttpClientHandler { Credentials = new NetworkCredential(user, pass, domain) }); var pdf = await client.GetByteArrayAsync(url); return File(pdf, "application/pdf", "monthly.pdf");
以下の方法で、例えば Forms 認証をクリアしたら、
「サーバ信頼セキュリティ モデル」で認証してアクセスする。
-
Windows FormsやASP.NETからSSRSのレポートを利用する
ASP.NET編 [SSRS with Bing Maps #9]ネスケラボ
http://blog.nextscape.net/archives/Date/2012/06/1716-
偽装する。
<identity impersonate="true"/>
-
IReportServerCredentials を実装する
IReportServerCredentials を実装して ReportViewer に渡すと、
アプリの処理でレポートにアクセスするユーザーを動的に変更することができる。
-
上記と同様に、以下の
「ベース クライアント セキュリティ モデル」方法でベースクライアントを
偽装する。
-
Windows FormsやASP.NETからSSRSのレポートを利用する
ASP.NET編 [SSRS with Bing Maps #9]ネスケラボ
http://blog.nextscape.net/archives/Date/2012/06/1716-
"ベースクライアント"を偽装する。
<identity impersonate="true" userName="accountname" password="password" />
-
IReportServerCredentials を実装する
IReportServerCredentials を実装して ReportViewer に渡すと、
アプリの処理でレポートにアクセスするユーザーを動的に変更することができる。
-
昔は、コチラが必要だったと思いますが、簡単に実装可能な方法がサポートされた?
補足(原文の疑問への回答:委任は不要になった、が条件付き): 「昔は
委任が必要だったと思いますが」という記述は
正確な観察である。整理して答える。【なぜ昔は委任(Kerberos 制約付き委任)が必要だったか】 ブラウザ ──Windows 認証──▶ ASP.NET アプリ ──?──▶ SSRS ↑ ここで利用者の 資格情報を「そのまま」 渡したい → Windows 認証は【1 ホップしか越えられない】(ダブル ホップ問題) → 利用者として SSRS へ行くには【Kerberos 委任の構成】が必要 ・SPN の登録 ・AD で「委任を信頼する」設定 ・IIS のアプリケーション プール ID の調整 → 【AD 管理者の作業が要る】= 面倒
IReportServerCredentialsが解決したこと:public class MyReportCredentials : IReportServerCredentials { // ① 固定のサービス アカウントで SSRS へ接続する public System.Net.ICredentials NetworkCredentials => new System.Net.NetworkCredential("svc_report", "***", "CORP"); // ② または、SSRS 側で「利用者を名乗る」(偽装) public bool GetFormsCredentials( out Cookie authCookie, out string userName, out string password, out string authority) { authCookie = null; userName = password = authority = null; return false; } public WindowsIdentity ImpersonationUser => null; }reportViewer.ServerReport.ReportServerCredentials = new MyReportCredentials();つまり、「委任を構成する」代わりに
「アプリが固定アカウントで接続する」ことができるようになった——
これが原文の言う「簡単に実装可能な方法」である。ただし、この方式には条件が付く。
方式 認可(誰が何を見られるか)の判断 委任(利用者を引き継ぐ) SSRS 側の権限設定がそのまま効く 固定アカウント接続 SSRS からは全員が同じユーザーに見える ★ 【固定アカウント接続の落とし穴】 SSRS 側の「このフォルダは営業部だけ」という権限が【効かなくなる】 → 全員が svc_report として接続するため → 【アプリ側で認可を実装する責任が生じる】 さらに、レポートのパラメータを改竄されると 見えてはいけないデータが見える可能性がある → 例: /Report?deptId=99 を書き換えて他部署のデータを見る → 【パラメータの検証をアプリ側で必ず行う】これが「サーバ信頼セキュリティ モデル」の
本質である。
**「サーバを信頼する」=「認可の責任がアプリ側に移る」**という
トレードオフを、本ページの 2 つのモデルは表している。
モデル 誰が SSRS に接続するか 認可の責任 ベース クライアント セキュリティ モデル 固定のベース クライアント( userNameを config に書く)アプリ側 サーバ信頼セキュリティ モデル アプリのプロセス ID / 動的に決めた ID アプリ側 委任(本ページの対象外) 利用者本人 SSRS 側
補足(
<identity impersonate>の現在の注意点): 原文が示す
Web.configの設定には、現在は明確な問題がある。<!-- ✗ パスワードを平文で書いている --> <identity impersonate="true" userName="accountname" password="password" />【問題】 ① 【パスワードが平文】で web.config に載る → ソース管理に入る、バックアップに残る、閲覧されうる ② パスワード変更のたびに全サーバの web.config を書き換える ③ 監査上、指摘を受ける当時からある緩和策:
・aspnet_regiis -pe で【web.config のセクションを暗号化】する aspnet_regiis -pe "system.web/identity" -app "/MyApp" → DPAPI または RSA でマシン単位に暗号化される現在の推奨:
手段 内容 アプリケーション プール ID を使う impersonateを使わず、プール ID に SSRS の権限を与えるgMSA(グループ管理サービス アカウント) パスワード管理が不要。AD が自動で回す ★ Azure Key Vault / Secret Manager 資格情報を外部の保管庫に マネージド ID(Azure) 資格情報そのものが不要になる gMSA が Windows 環境での現在の定石である。
・パスワードを人が知らない(AD が 30 日ごとに自動更新) ・config にパスワードを書かない ・IIS のアプリケーション プール ID に設定できる
<identity impersonate="true"/>(ユーザー名なし)の方は、
利用者の資格情報でスレッドを偽装するもので、性質が異なる。
こちらはダブル ホップ問題を解決しない(委任の構成が別途要る)
点に注意する(委任)。
補足(Forms 認証と SSRS を組み合わせる場合の全体像): 原文の
「例えば Forms 認証をクリアしたら」という前提を、
設計として整理しておく。【構成】 ブラウザ │ ① Forms 認証(アプリ独自のログイン画面) ▼ ASP.NET アプリ │ ② 認可: このユーザーはこのレポートを見て良いか? ★ アプリの責任 │ ③ パラメータの検証・強制: 部署 ID をサーバ側で決める ★ ▼ SSRS(固定アカウントで接続)② と ③ を省くと重大な脆弱性になる。
// ✗ 利用者が指定した deptId をそのまま渡す reportViewer.ServerReport.SetParameters( new ReportParameter("deptId", Request["deptId"])); // ○ ログイン中のユーザーから【サーバ側で導出する】 var deptId = _userService.GetDepartmentId(User.Identity.Name); reportViewer.ServerReport.SetParameters( new ReportParameter("deptId", deptId.ToString()));SSRS 側にも保険を掛けるなら、
レポートのデータセットに条件を埋め込む
(WHERE dept_id = @deptIdを必ず通す)。
Tags: 移行, .NET開発, ASP.NET, 認証基盤
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。