2025年10月6日月曜日

【開発】ASP.NET Core Identityを自分のユーザーマスタに組み込む:独自テーブルと連携するやさしい手順

最近、asp.net coreで開発をしていて、改めてその良さがわかったのでまとめたいと思います。

ASP.NET Core Identityは、ログイン機能を“ほぼ自動で”実装してくれる便利な仕組みです。ユーザー登録・パスワード管理・ロックアウト・2段階認証まで、すべて組み込み済みです。

ただし最初につまずくのがここです。

「うちのシステムには、すでに独自の社員マスタ(UserMaster)テーブルがある。
Identityのテーブルとはどうつなげばいいの?」

本記事では、レガシーな「社員マスタ」と、Identityの「認証管理」をきれいに統合する方法を解説します。

---

1. Identityの正体をざっくり理解する

Identityを使うと、自動的に次のようなテーブルが生成されます。

テーブル名役割
AspNetUsersユーザーの基本情報(ID、メール、パスワードハッシュなど)
AspNetRoles権限(Admin, Userなど)
AspNetUserRolesユーザーとロールの紐づけ
AspNetUserClaimsユーザーの属性(メール確認済みなど)

つまり、AspNetUsers が“認証の中心”です。 このテーブルに、あなたのシステム独自の情報(部署、社員番号、権限区分など)を追加すればOKです。

---

2. IdentityUserを継承してカラムを追加する(最も基本的な方法)

最もシンプルなやり方は、IdentityUserを継承したクラスに独自カラムを追加することです。

using Microsoft.AspNetCore.Identity;

public class ApplicationUser : IdentityUser
{
    public string EmployeeCode { get; set; }   // 社員コード
    public string Department { get; set; }     // 部署名
}

DbContextの拡張

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

public class AppDbContext : IdentityDbContext<ApplicationUser>
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Product> Products { get; set; }  // 他のテーブルも共存可能
}

Program.cs(またはStartup)で設定

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

Migrationで反映

dotnet ef migrations add AddIdentityTables
dotnet ef database update

これで、AspNetUsersに新しい列(EmployeeCode、Department)が追加されます。

---

3. 既存の「UserMaster」テーブルを残したまま、Identityと連携する

public class ApplicationUser : IdentityUser
{
    public int UserMasterId { get; set; }    // 既存テーブルの主キー
    public virtual UserMaster UserMaster { get; set; }
}

DbContextで関連付け

public class AppDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<UserMaster> UserMasters { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<ApplicationUser>()
            .HasOne(u => u.UserMaster)
            .WithOne()
            .HasForeignKey<ApplicationUser>(u => u.UserMasterId);
    }
}
---

4. ログイン画面の実装例

public class AccountController : Controller
{
    private readonly SignInManager<ApplicationUser> _signInManager;

    public AccountController(SignInManager<ApplicationUser> signInManager)
    {
        _signInManager = signInManager;
    }

    [HttpPost]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
        var result = await _signInManager.PasswordSignInAsync(
            model.UserName, model.Password, model.RememberMe, lockoutOnFailure: false);

        if (result.Succeeded)
        {
            return RedirectToAction("Index", "Home");
        }

        ModelState.AddModelError("", "ログインに失敗しました。");
        return View(model);
    }
}
---

5. Identity拡張のコツと注意点

項目内容
カラム追加時ApplicationUserに列を追加したら、必ずdotnet ef migrations addを実行
外部キー連携循環参照に注意し、Navigation Propertyを最小限に
既存データ活用IdentityのUserIdと社員コードのマッピング方針を決めておく
---

6. まとめ

ASP.NET Core Identityは「全部作り直し」ではなく、既存のユーザーマスタと共存できる認証エンジンです。

  • パスワードの暗号化・認証管理 → Identityに任せる
  • 社員情報・業務ロジック → 自社マスタで管理

一言で言うと:
Identityは「既存システムの認証エンジンとして使う」のが正解です。

2025年7月2日水曜日

恥ずかしい!Wi-Fiパスワードと暗号化キーを間違えた息子と、正しかった父

 


先日、父から「パソコンがWi-Fiに繋がらない」と連絡がありました。私は「ルーターに貼ってあるシールにアクセスポイント名とパスワードが書いてあるから、それを入れれば繋がるよ」と自信満々に答えました。しかし、父は「それでも繋がらない」と言うばかり。

おかしいなと思い、詳しく聞いてみると、どうやら父はルーターのシールに記載されている別の文字列を入力していたようでした。よくよくシールを確認してみると、私が「パスワード」だと思い込んでいたのは、実は**「暗号化キー」**だったのです!

そして、父が入力していたのは、なんとルーターの管理画面にログインするためのIDとパスワード。私は「パスワード入れた?」と何度も確認していましたが、父は全く別のパスワードを入れていたわけです。

「パスワード」と「暗号化キー」:その違い、説明できますか?

皆さんも、もしかしたら私と同じような勘違いをしているかもしれませんね。ここで、Wi-Fi接続における「パスワード」と「暗号化キー」の違いについて、簡単に説明させてください。

一般的にWi-Fiに接続する際に入力する「パスワード」とは、正確には**「暗号化キー」**のことを指します。Wi-Fiの通信は、傍受されると内容が漏洩する危険性があるため、暗号化されています。この暗号化された通信を復号(元に戻すこと)するために必要なのが「暗号化キー」なのです。

このキーがあることで、許可された端末だけがWi-Fiネットワークに接続できるようになり、安全にインターネットを利用できます。もしこのキーがなければ、誰でも簡単にあなたのWi-Fiにただ乗りできてしまう、ということになります。

ルーターのシールに記載されている「パスワード」という表記も、結局は「暗号化キー」のことを指している場合がほとんどです。一方で、管理画面のパスワードは、ルーターの設定を変更する際に使用する、文字通り「管理用のパスワード」です。

偉そうにした息子より、パソコンが不慣れな父の方が正しかった

「パスワードを入れたら繋がる」と偉そうにアドバイスしていた私ですが、まさか自分が根本的に間違っていたとは…。パソコンに不慣れな父の方が、実は的確な情報を確認し、試行錯誤していたのです。結果的に、父の言うことをきちんと聞かず、自分の思い込みだけで判断していた私が間違っていました。

この一件で、私は大きな反省をしました。どんなにITに詳しいと思っていても、思い込みや知識の欠落があることを痛感した出来事です。そして、何よりも、困っている人の話をきちんと聞くことの大切さを改めて学びました。

まとめ:Wi-Fi接続で困ったら、まずはルーターのシールを隅々まで確認!

もしWi-Fi接続で困った際は、以下の点を再確認してみてください。

 * アクセスポイント名(SSID):接続したいWi-Fiの名前です。

 * 暗号化キー(パスワード):Wi-Fiに接続するために必要な文字列です。ルーターのシールに「パスワード」と書いてあることが多いですが、これは暗号化キーのことです。

 * 管理画面のIDとパスワード:これはルーターの設定を変更するためのもので、Wi-Fi接続時には使いません。

今回の経験を通して、改めて父に感謝です。そして、これからはもっと謙虚に、そして丁寧に、周囲の困りごとに耳を傾けようと心に誓いました。


2025年6月29日日曜日

Apache Tomcatの起動状態がstoppedと表示される現象の解説と解決策


Apache Tomcatを運用していると、Webサイトは問題なく稼働しているにもかかわらず、sudo /etc/init.d/tomcat statusコマンドを実行すると**「stopped」と表示されてしまう**という奇妙な現象に遭遇することがあります。今回はこの現象の原因と、その解決策について詳しく解説します。

現象の概要

この現象は、Tomcatが正常に動作しているにもかかわらず、システム起動スクリプトがTomcatプロセスを正しく認識できないために発生します。結果として、statusコマンドの出力は「stopped」となり、管理上混乱を招く可能性があります。

原因:psコマンドの出力文字数制限

この問題の根源は、/etc/init.d/tomcatスクリプト内でTomcatプロセスを検出するために使用されているpsコマンドのオプションにあります。具体的には、以下の行が関係しています。

INSTANCES=`ps --columns 512 -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l`



このコマンドは、システム上で実行されているプロセスの中からTomcatに関連するものを検索しています。ポイントは--columns 512というオプションです。これはpsコマンドの出力行の最大文字数を512文字に制限するものです。

Tomcatの起動時には、そのプロセス情報(特にJavaの起動オプションなど)が非常に長くなることがあります。もしTomcatの起動コマンドラインが512文字を超えてしまうと、ps --columns 512 -aefの出力では、その長いコマンドラインが途中で切り詰められてしまいます。

なぜ問題になるのか?

Tomcatのプロセスを特定するために、スクリプトは切り詰められたpsの出力に対してさらにgrep org.apache.catalina.startup.Bootstrapというフィルタリングを行っています。しかし、もしorg.apache.catalina.startup.Bootstrapという文字列が、--columns 512によって切り詰められた部分よりも後ろに位置していた場合、grepはその文字列を見つけることができません。

結果として、スクリプトはTomcatプロセスが稼働していないと判断し、「stopped」と表示してしまうのです。

解決策:--columnsオプションの調整または削除

この問題を解決するには、/etc/init.d/tomcatスクリプト内のpsコマンドから--columns 512オプションを削除するか、より大きな値に変更します。

1. --columns 512を削除する

最も簡単な方法は、このオプションを完全に削除することです。これにより、psコマンドはプロセス情報を切り詰めることなく完全な形で出力するようになります。

# 変更前

INSTANCES=`ps --columns 512 -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l`


# 変更後

INSTANCES=`ps -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l`



2. --columnsの値を増やす

もし何らかの理由で--columnsオプションを残したい場合は、Tomcatの起動コマンドラインが確実に収まるような十分大きな値(例: 1024や2048など)に変更します。

# 変更前

INSTANCES=`ps --columns 512 -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l`


# 変更後(例: 2048に変更)

INSTANCES=`ps --columns 2048 -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l`



変更後の確認

スクリプトを修正したら、Tomcatを再起動する必要はありません。そのままsudo /etc/init.d/tomcat statusコマンドを実行し、今度は「running」と正しく表示されることを確認してください。

この現象は少し戸惑うかもしれませんが、原因を理解して適切な修正を行うことで、Tomcatの運用状況を正しく把握できるようになります。


2025年5月25日日曜日

【体験談】OCI Architect Associateに2回目で合格!Udemy活用で学習効率アップ【2025年版】




今回は、Oracle Cloud Infrastructure(OCI)Architect Associate認定試験に2回目でようやく合格できた体験を書きたいと思います。 

 特に、Udemyを使った学習法が合格の決め手になったので、同じ資格を目指している方の参考になれば幸いです。

 ⸻ 

 1回目の失敗:勉強不足 と油断

 実は、1回目の試験では「なんとかなるだろう」と甘く見てしまい、公式ドキュメントをざっと読んだだけで受験しました。

結果は当然、不合格。 OCIのサービスは範囲が広く、設計やセキュリティ、ネットワーク、OCI特有の概念など、最初は戸惑いました。 

 公式の模擬問題が着手できたのは前日の夜! それまで、動画を一からみていたのですが、それがよくなかったかもしれないです。 

 二倍速でみていて、それなりに理解できていたと思っていたのですが、 

  どうしても時間がかかる 

とても解説は分かりやすく、理解の助けにはなったのですが、動画教材は見ずに、試験だけを考えるなら、直接問題を何度も解き直したほうがよかった、、、と今では思います。

また、動画を全部見て理解できたことで満足し、油断しました。試験のための記憶すべきことへの対策が疎かになっていたと思います。



 ⸻ 
 Udemyを使った2回目の挑戦 

 2回目の挑戦では、しっかりと対策するために評判の良いUdemy講座を活用しました。 

 私が実際に使ってよかったのは、以下の講座です:


今回初めてudemyを使ってみたのですが、良かったので共有します。

 おすすめポイント: 
 • 中断しても再開がスムーズ(udemy)
資格試験で一番大変なのが時間の確保!
そして、時間が確保できても、環境が良くないと効果が激減します。

当初私は公式の教材ばかりやっていましたが、オラクルのmy learnサイトは、よくセッションが切れて、再ログインが必要になります。

それだけでなく、再ログインしても、なぜがログインできないことがあり、再開が大変でした。

udemyで、移動時間でも昼休みでも、いつでも再開できる、これは大きかったです。

・公式と違う気づきがある(教材)
トラフィック料金は、OCIを使うと他のクラウドサービスに比べ、安くなると思います。
特にデータエグレスが月10TBまで無料なのはすごい。
大体無料になると思うのですが、
この教材で、有料になる場合の問題を間違えてしまい、いい勉強になりました。
もし、ある領域が苦手だ、という方がいらっしゃる場合、こちらの問題を解いてみると、公式とは違う気づきが得られるのではないでしょうか。

 ⸻ 
 学習スケジュールと勉強法のコツ 2回目の試験では以下の優先順位での学習を行いました。

udemy
公式の模擬問題集(PDF)
公式の練習問題(Web)

※公式の練習問題(Web)も、ある程度まとまった時間が取れる人なら、情報量としては一番多いので優先してもいいかも。

最終的には、90%取ることができました。


 ⸻
 

AWSやAzureに比べてまだ受験者が少ないOCI資格は、場合によっては差別化にもなりますね。

 ⸻
 最後に:これから受験する方へ OCI Architect Associateはしっかり準備すれば、未経験でも十分合格できます。私のように1度失敗しても、Udemyをうまく使えば合格は現実的です。 


 ぜひ、あなたもOCI資格を武器にキャリアアップを目指してください!

2025年5月19日月曜日

Cocosはカレー屋?

 



知り合いに言われて今日ハッとした。


CoCo壱とココスって似てるよね。


???どこが?


えっ。

えっ。


CoCo壱



ココス


色が黄色でcocoってところまで一緒か。

面積的には半分以上の情報で似通っている、、、

そもそも「ココ」って何だ?

CoCo壱番屋(正式名:カレーハウスCoCo壱番屋)

創業は1978年。名古屋発のカレー専門店チェーン。

「CoCo」は実は創業者の一人が好きだったジャズ喫茶の名前が由来なんだとか。

ココス(COCO’S)

元々アメリカ生まれ。日本には1978年に上陸。

「COCO’S」は「Comfortable & Casual(快適でカジュアル)」の略…かと思いきや、アメリカの創業者の名前が“ココ”だったという説も。


つまり両方とも「ココ」って名前の人が身近にいたか、好きだったという、割とパーソナルな理由で「ココ」になってるらしい。


、、、

なんかCoCo壱食べたくなってきた。

でも、炭水化物ばかりだからな、、、と思っていたらこんなのが。

友達が来た時ネタに出してみるか