Memo

メモ > 技術 > フレームワーク: SpringBoot > 認証

■認証
Spring Boot Starter Securityを導入することで対応できる pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
src/main/java/com/example/demo/config/SecurityConfig.java
package com.example.demo.config; import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { //http.authorizeRequests().anyRequest().permitAll(); http .formLogin((form) -> form // 認証を行うURL .loginProcessingUrl("/admin/") // ログインページのURL .loginPage("/admin/") // ログインユーザ名の項目 .usernameParameter("username") // ログインパスワードの項目 .passwordParameter("password") // 認証に成功したときにリダイレクトするURL .defaultSuccessUrl("/admin/home") // 認証に失敗したときにリダイレクトするURL .failureUrl("/admin/?error") // すべてのユーザがアクセス可能 .permitAll() ) .logout((logout) -> logout // ログアウトページのURL .logoutUrl("/admin/logout") // ログアウトしたときにリダイレクトするURL .logoutSuccessUrl("/admin/") ) .authorizeHttpRequests((requests) -> requests // CSSなどはログイン無しでもアクセス可能 .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // ログイン無しでもアクセス可能なURL .requestMatchers("/", "/now", "/task/**", "/dev/**").permitAll() // 「/admin/」へのアクセスには「ADMIN」権限が必要 .requestMatchers("/admin/**").hasRole("ADMIN") // 他のページはすべて認証が必要 .anyRequest().authenticated() ); return http.build(); } @Bean public UserDetailsService userDetailsService() { User.UserBuilder users = User.withDefaultPasswordEncoder(); // 認証情報1 UserDetails admin = users .username("admin") .password("abcd1234") .roles("ADMIN") .build(); // 認証情報2 UserDetails guest = users .username("guest") .password("abcd1234") .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(admin, guest); } }
src/main/java/com/example/demo/controller/AdminController.java
package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class AdminController { @GetMapping(value = "/admin/") String index() { return "admin/index"; } @GetMapping(value = "/admin/home") String home() { return "admin/home"; } }
templates/layout/backend.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> <head> <meta charset="UTF-8"> <title>Admin</title> </head> <body> <header th:fragment="header"> <h1>Demo</h1> </header> <th:block layout:fragment="content"></th:block> <footer th:fragment="footer"> <p><small>This is demo site.</small></p> </footer> </body> </html>
src/main/resources/templates/admin/index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/backend}"> <head> <title>ログイン | Admin</title> </head> <body> <th:block layout:fragment="content"> <main> <p>ログインページ。</p> <p th:if="${param.error}">ユーザ名またはパスワードが異なります。</p> <p th:if="${param.logout}">ログアウトしました。</p> <form th:action="@{/admin/}" method="post"> <dl> <dt>ユーザ名</dt> <dd><input type="text" name="username" value=""></dd> <dt>テキスト</dt> <dd><input type="password" name="password" value=""></dd> </dl> <p><input type="submit" value="ログイン"></p> </form> </main> </th:block> </body> </html>
src/main/resources/templates/admin/home.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/backend}"> <head> <title>ホーム | Admin</title> </head> <body> <th:block layout:fragment="content"> <main> <p>管理画面にログインしています。</p> <form th:action="@{/admin/logout}" method="post"> <p><input type="submit" value="ログアウト"></p> </form> </main> </th:block> </body> </html>
これで http://localhost:8080/ は通常どおりアクセスでき、 http://localhost:8080/admin/ から先に進もうとすると認証を求められる 認証を求めるページや認証情報は、SecurityConfig.java で指定している 「/admin/**」のようなURL指定については以下を参照 アスタリスク1つだと同階層のみ対象だが、アスタリスク2つだと指定階層以下が対象となる antMatchersのワイルドカードについて - てのひら https://www.tenohira.xyz/tech/spring-antmatchers-wildcard/ アクセスできるURLは以下のようにしている 「原則ログインが必要なシステム。ログイン画面など一部ページのみ誰でもアクセスできる」という場合はこれで良さそうだが、
.authorizeHttpRequests((requests) -> requests // CSSなどはログイン無しでもアクセス可能 .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // ログイン無しでもアクセス可能なURL .requestMatchers("/", "/now", "/task/**", "/dev/**").permitAll() // 「/admin/」へのアクセスには「ADMIN」権限が必要 .requestMatchers("/admin/**").hasRole("ADMIN") // 他のページはすべて認証が必要 .anyRequest().authenticated() );
「/admin/ は管理者用ページ。他は誰でもアクセスできるページ」という場合、以下くらいの指定でもいいかもしれない
.authorizeHttpRequests((requests) -> requests // 「/admin/」へのアクセスには「ADMIN」権限が必要 .requestMatchers("/admin/**").hasRole("ADMIN") // 他のページはすべてアクセス可能 .anyRequest().permitAll() );
ログイン、ログアウトの実装|Javaの基礎を学び終えたアナタに贈る, SpringBoot/SpringSecurityによる掲示板開発ハンズオン https://zenn.dev/angelica/books/52be1e365c61ea/viewer/1c1ebe Spring Boot ログイン画面 - 公式サンプルコード https://spring.pleiades.io/guides/gs/securing-web/ Spring Boot でSpring Securityを使ってみる(SecurityFilterChain) - Qiita https://qiita.com/TaikiTkwkbysh/items/9e2a7dfdf9f0bed9e779 インメモリ認証 :: Spring Security - リファレンス https://spring.pleiades.io/spring-security/reference/servlet/authentication/passwords/in-memory.html Spring Boot にて Spring Security を使用した直後の認証の仕組みをソースコードとともに確認する https://zenn.dev/kiyotatakeshi/articles/fc593c768ad7e0 SpringSecurityの導入/CSRF対策|Javaの基礎を学び終えたアナタに贈る, SpringBoot/SpringSecurityによる掲示板開発ハンズオン https://zenn.dev/angelica/books/52be1e365c61ea/viewer/f0683a timestamp status 999 error none message no message available - Qiita https://qiita.com/TBATYOF/items/4e87a6297cc78f43e842 WebSecurityConfigurerAdapter を継承するのは古い方法で、SecurityFilterChain を定義するのが新しい方法らしい WebSecurityConfigurerAdapterが非推奨になってた https://volkruss.com/posts/p2691/ Spring Security 5.4〜6.0でセキュリティ設定の書き方が大幅に変わる件 - Qiita https://qiita.com/suke_masa/items/908805dd45df08ba28d8 最新の6.0で学ぶ!初めてのひとのためのSpring Security | ドクセル https://www.docswell.com/s/MasatoshiTada/KGVY9K-spring-security-intro 以下は古い書き方だが参考までに Spring Securityの認証のサンプル(SpringBoot) | ITSakura https://itsakura.com/spring-security-boot 【SpringBoot入門】Spring Securityで認証機能 - Qiita https://qiita.com/morioheisei/items/ecfeee4860944d0b4a3b Spring Boot入門:Spring Securityで認証と認可 | ツチヤの備忘録 https://www.tsuchiya.blog/spring-boot-step7/

Advertisement