Skip to content

MS_ASPNETAndSSRS

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

ASP.NETとSSRSの連携と認証

連携

ReportViewer を使用して連携可能。

補足(連携方式は 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 に渡すと、
      アプリの処理でレポートにアクセスするユーザーを動的に変更することができる。

IReportServerCredentials

昔は、コチラが必要だったと思いますが、簡単に実装可能な方法がサポートされた?

補足(原文の疑問への回答:委任は不要になった、が条件付き): 「昔は
委任が必要だったと思いますが」という記述は
正確な観察である。整理して答える。

【なぜ昔は委任(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, 認証基盤

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally