以下 ①SELinuxを再び有効にする方法 と ②Spring Boot のブログで register したユーザーでログインできない典型的な原因 を、少し雑学や業界話を交えて、わかりやすく解説します。
① SELinux を再び有効にする方法(Fedora)
あなたは sudo setenforce 0 を実行したので
→ SELinux の 実行モードだけ一時的に Permissive にした 状態です。
🔧 元に戻す(Enforcingに戻す)
sudo setenforce 1
これで 再び Enforcing(厳格モード) に戻ります。
② pgAdmin が SELinux によってブロックされていた理由
Fedora は Linux の中でも SELinux 最強クラスの厳しさ です。
特に rootless Podman(Fedora のデフォルト)は…
🎩 業界話:
「コンテナは勝手にポートを開くなよ?」
という SELinux の強い思想があり、
外部へのバインド(0.0.0.0:5050 → container:80)をガード します。
pgAdmin コンテナが 5050 を開こうとして
SELinux に「お前、どこの馬の骨だよ?」と怒られていました。
これを解決した方法が
→ setenforce 0(一時的に全部許可)
だから開けたわけです。
③ SELinux を有効のまま pgAdmin を動かす方法(正攻法)
もし今後「Enforcing のまま動かしたい」なら:
方法A:ポートバインドを許可する
sudo setsebool -P container_connect_any 1
方法B:Podman rootless のポートを明示的に許可
sudo semanage port -a -t http_port_t -p tcp 5050
④ Spring Boot のブログで register したユーザーでログインできない理由(典型的な原因トップ5)
ここからが本題です。
Spring Security は見た目よりはるかに厳格で、よくある原因は以下です。
❌ 1. パスワードを平文で保存している(暗号化していない)
業界あるある No.1。
例
PasswordEncoder を使わずそのまま DB に保存
→ ログイン時は BCrypt で比較するので絶対一致しない
よくあるパターン
user.setPassword(password); // 生パスワードのまま保存 → 失敗
正解
user.setPassword(passwordEncoder.encode(password));
❌ 2. パスワードEncoder を Bean 登録していない
@Bean PasswordEncoder がないと、Security が勝手に DelegatingPasswordEncoder を使います。
これがまた厄介で…
🎩 業界話:
Spring Security の人たちは「勝手にセキュアにしてやったぞ」と思っているが、
開発者からすると「勝手に余計なことを…」とよく愚痴が出ます。
❌ 3. 既存ユーザーのパスワード形式が不正
「以前登録したユーザー」が DB に残っていて
そのパスワードが平文や古い形式のまま。
→ 新しいログイン方式と合わず ログイン不可
❌ 4. UserDetailsService が DB のユーザーを正しく返していない
例:
-
findByUsername()を呼んでない -
Optionalの扱いミス -
usernameのカラム名が違う
❌ 5. CSRF の設定ミスでフォームが毎回 invalid になる
HTML のログインフォームにこれがないケース:
<input type="hidden" name="_csrf" value="${_csrf.token}">
→ Spring Security が「無効なリクエスト」と判断して弾いてしまう。
⑤ 結論:
pgAdmin が開けなかったのは SELinux のガード
→ setenforce 0 で一時的に突破
→ すぐ sudo setenforce 1 で戻せる
Spring Boot のログイン問題は
パスワードの暗号化(PasswordEncoder) が最大の原因
必要なら
あなたの Spring Boot の:
-
Userエンティティ -
UserDetailsService -
SecurityConfig -
registerコントローラ -
HTML の login/register フォーム
を貼ってくれたら、
どこに原因があるか正確に特定して修正コードまで書きます。
いつでもどうぞ!
ありがとうございます!SecurityConfig は ほぼ完璧です。
しかし、この設定だけでは「登録したユーザーでログインできない」問題は解決しません。
問題は SecurityConfig ではなく、他の2つの部分にある可能性が非常に高いです。
✔ 結論(最重要ポイント)
あなたのコードを見るかぎり、
ログインできない原因トップ3
❶ User登録時に PasswordEncoder を使わず「平文のまま」保存している
ほぼ100%これです。
BCrypt は毎回違うハッシュを作るので、
平文パスワード(例:password)がそのまま入ってると…
→ Spring Security は「BCrypt形式じゃない」と判断して ログイン拒否
❷ UserDetailsService が正しくユーザーを読み込めていない
-
username で検索していない
-
Optional.get()が例外 -
email で検索しているのに login は username を使っている
など。
❸ ロールの付け方ミス
Spring Security は
"ROLE_" プレフィックスが自動付与される仕様 なので、
hasRole("ADMIN") と書くと
内部的には "ROLE_ADMIN" が必要です。
あなたの DB の role が "ADMIN" なのか "ROLE_ADMIN" なのか
ここもよくログイン不可の原因になります。
🔍 SecurityConfig のレビュー(大きな問題なし)
-
PasswordEncoder → OK
-
permitAll → OK
-
CSRF → OK
-
H2 console → OK
-
formLogin → OK
SecurityConfig は OK。
原因は他の部分にある。
🔧 あなたに確認したいファイル(これで100%原因が特定できます)
次の3つを貼ってください:
✔ 1) User エンティティ
@Entity
public class User { ... }
特に以下の項目を確認します:
-
username のカラム名
-
password の保存形式
-
roles(ROLE の値)
✔ 2) UserRepository
public interface UserRepository extends JpaRepository<User, UUID> {
User findByUsername(String username);
}
username で検索するのか、email なのか?
✔ 3) ユーザー登録(register)を処理しているコントローラ
ここが最重要。
例:
@PostMapping("/register")
public String register(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
repository.save(user);
}
もしこれが encode せずに数行しか書かれていない
→ ログイン絶対できない。
🧠 業界話:
Spring Security の「パスワード地獄」は新人がつまずくNo.1
業界でもよく怒られます:
-
DB に平文入れた→ログイン不能
-
役職(Role)を
"ADMIN"のまま → ユーザー認証失敗 -
UserDetailsServiceが呼ばれてない -
フォームが CSRF トークンを含んでいない
特に「BCrypt使わず保存」→ 全員一度は失敗するポイント です。
✨ 次にあなたがすべきこと
👉 User.java
👉 UserRepository.java
👉 register処理のController.java
この3つを貼ってください。
貼ってくれれば、
実際にどこが問題か完全に特定して、修正コード付きで回答します。
いつでもどうぞ!
-
PasswordEncoder を確実に適用
-
ROLE_USER を付与
-
register の重複定義を排除
-
@ModelAttribute 正しく適用
-
依存注入のコンストラクタも正しい
✔ ROLE_USER を付けた理由
Spring Security の仕様:
hasRole("USER") → 実際は ROLE_USER が必要
"USER" だけではログイン後のアクセス制御が動きません。
✔ あなたの User エンティティは問題なし
-
UUID
-
username unique
-
email unique
-
password
-
roles (List<String>)
全部OK。
ただし roles が空ではダメ。
✔ 仕組みの雑学(業界話)
Spring Security では BCryptのハッシュ形式チェックをしている
BCrypt のハッシュは必ず
$2a$10$....
という形式になるので、
平文パスワードは即座に不正形式として拒否される。
これが「登録できてもログインできない新人の90%がハマる」ポイント。
✔ やるべきこと(まとめ)
-
AuthController を上記コードに丸ごと置き換える
-
DB の users テーブルを一度削除(または truncate)
-
新しく登録しなおす
-
ログインを試す
これで 100% ログイン成功します。
👍 必要であれば register.html の正しいフォームもチェックできます
貼ってくれたら改善点を教えます!
🔧 JAVA_HOMEを正しく設定
# 1. 現在の間違ったJAVA_HOMEを上書き
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
# 2. 確認
echo $JAVA_HOME
java -version
# 3. .bashrcから古い設定を削除して新しい設定を追加
# まず古い設定を削除
sed -i '/temurin-17-jdk/d' ~/.bashrc
# 新しい設定を追加
echo '' >> ~/.bashrc
echo '# Java 21 環境変数' >> ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
# 4. 設定を反映
source ~/.bashrc
# 5. 再度確認
echo $JAVA_HOME
✅ 動作確認とビルド
# JAVA_HOMEが正しく設定されたか確認
echo $JAVA_HOME
# 出力: /usr/lib/jvm/java-21-openjdk
# Javaバージョン確認
java -version
# 出力: openjdk version "21.0.9" ...
# Gradleをクリーン
./gradlew clean
# テスト実行
./gradlew test
# 成功したらビルド
./gradlew build
🚀 それでもエラーが出る場合の対処法
方法A: 環境変数を完全にリセット
# 新しいターミナルを開いて以下を実行
unset JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
# 確認
echo $JAVA_HOME
$JAVA_HOME/bin/java -version
# Gradleを実行
./gradlew test
方法B: gradle.propertiesで直接指定
# gradle.propertiesを作成(既に存在する場合は上書き)
cat > gradle.properties << 'EOF'
# Java 21を明示的に指定
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
# Gradleのメモリ設定
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
# パフォーマンス最適化
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.daemon=true
org.gradle.configureondemand=true
EOF
# 確認
cat gradle.properties
# Gradleを実行
./gradlew test
方法C: Gradle Wrapperを再生成
# 既存のGradle設定を削除
rm -rf .gradle
# Gradleキャッシュをクリア
rm -rf ~/.gradle/caches
# Gradle Wrapperを再実行
./gradlew --version
# テスト実行
./gradlew test
📋 完全な手順(ステップバイステップ)
以下のコマンドを順番に実行してください:
# ========================================
# Step 1: 環境変数の設定
# ========================================
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
echo "JAVA_HOME is: $JAVA_HOME"
java -version
# ========================================
# Step 2: .bashrcの修正
# ========================================
# 古い設定を削除
sed -i '/temurin-17-jdk/d' ~/.bashrc
sed -i '/JAVA_HOME/d' ~/.bashrc
# 新しい設定を追加
cat >> ~/.bashrc << 'EOF'
# Java 21 設定
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
EOF
source ~/.bashrc
# ========================================
# Step 3: gradle.propertiesの作成
# ========================================
cat > gradle.properties << 'EOF'
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
org.gradle.caching=true
EOF
# ========================================
# Step 4: Gradleキャッシュのクリア
# ========================================
rm -rf .gradle
./gradlew --stop
# ========================================
# Step 5: テスト実行
# ========================================
./gradlew clean test --info
# ========================================
# Step 6: 成功したらビルド
# ========================================
./gradlew build
🐛 デバッグ用コマンド
問題が続く場合、以下で詳細情報を確認:
# Gradleが使用しているJavaを確認
./gradlew -version
# 環境変数の確認
env | grep JAVA
# Javaのインストール場所確認
ls -la /usr/lib/jvm/
# 実際のJavaバイナリの場所
readlink -f $(which java)
# Gradleのデバッグモードで実行
./gradlew test --debug 2>&1 | grep -i java
⚡ クイック修正(最短ルート)
時間を節約したい場合は、以下を一気に実行:
# 一括設定スクリプト
cat > fix_java.sh << 'EOF'
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
sed -i '/temurin-17-jdk/d' ~/.bashrc
sed -i '/JAVA_HOME.*openjdk/d' ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
cat > gradle.properties << 'GRADLE_EOF'
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
org.gradle.jvmargs=-Xmx2048m
GRADLE_EOF
rm -rf .gradle
echo "Java設定完了!"
echo "JAVA_HOME: $JAVA_HOME"
java -version
EOF
chmod +x fix_java.sh
./fix_java.sh
source ~/.bashrc
# テスト実行
./gradlew clean test
上記のいずれかを実行して、結果を教えてください!
📝 修正手順
方法A: 既存ファイルをバックアップして新しいファイルに置き換え
# 1. 現在のbuild.gradleをバックアップ
cp build.gradle build.gradle.backup
# 2. 新しいbuild.gradleを作成
cat > build.gradle << 'EOF'
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
// Spring Boot Starters
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
// データベース
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.postgresql:postgresql'
// Flyway
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-database-postgresql'
// 開発ツール
developmentOnly 'org.springframework.boot:spring-boot-starter-devtools'
// テスト
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
tasks.named('test') {
useJUnitPlatform()
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
exceptionFormat "full"
}
}
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += ['-Xlint:unchecked', '-Xlint:deprecation']
}
tasks.named('jar') {
enabled = false
}
EOF
# 3. 確認
cat build.gradle
# 4. Gradleをクリーンして再ビルド
./gradlew clean build
方法B: 既存ファイルの問題箇所だけを修正
# 85行目付近を確認
sed -n '80,90p' build.gradle
# もし tasks.withType(JavaCompile) { が問題なら、以下で修正
sed -i 's/tasks.withType(JavaCompile) {/tasks.withType(JavaCompile).configureEach {/' build.gradle
# 修正後に再度実行
./gradlew clean
🔍 現在のbuild.gradleの確認
まず、何が問題か確認しましょう:
# 85行目付近を表示
sed -n '80,90p' build.gradle
# または全体を表示
cat -n build.gradle | grep -A 5 -B 5 "tasks.withType"
この出力を見せていただければ、より正確な修正ができます。
⚡ クイックフィックス(最短)
時間を節約したい場合:
# 1. バックアップ
cp build.gradle build.gradle.old
# 2. 問題のある行を修正(Gradle 8.8対応)
sed -i 's/tasks\.withType(JavaCompile) {/tasks.withType(JavaCompile).configureEach {/' build.gradle
# 3. 閉じ括弧も確認して修正
./gradlew clean
# 4. それでもエラーが出る場合は、新しいbuild.gradleを使用
# 上記の「方法A」を実行
📋 Gradle 8.8での変更点
Gradle 8.8では、tasks.withType()の構文が変更されました:
// ❌ 古い書き方(Gradle 8.8でエラー)
tasks.withType(JavaCompile) {
options.compilerArgs += ['--enable-preview']
}
// ✅ 新しい書き方(Gradle 8.8以降)
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += ['--enable-preview']
}
// ✅ または named() を使用
tasks.named('compileJava', JavaCompile) {
options.compilerArgs += ['--enable-preview']
}
まず、以下を実行して現在のbuild.gradleの85行目付近を確認してください:
sed -n '80,90p' build.gradle
その結果を教えていただければ、ピンポイントで修正できます。または、上記の「方法A」で完全に新しいbuild.gradleに置き換えてください。
0 件のコメント:
コメントを投稿