前提・実現したいこと
お世話になっております。
Spring Security + Mybatis + MySQLでログイン実装を実現したく、今回投稿させていただきます。
発生している問題・エラーメッセージ
WARN 18184 --- [nio-8080-exec-1] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt boolean debugEnabled =user.isEnabled(); System.out.println("########################"); System.out.println(debugEnabled); System.out.println("########################"); String debugRole = user.getRole(); System.out.println("########################"); System.out.println(debugRole); System.out.println("########################"); の形でデバッグしてみましたが結果が org.springframework.security.core.userdetails.User [Username=demo, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_USER]] 。 お手数をおかけしますが、よろしくお願いいたします。
該当のソースコード
WebSecurityConfig.java /** * ユーザー認証設定クラス * @author hiromune mochida * @version 2021/01/18 */ @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthService userService; /** * パスワードハッシュ化 * @return BCryptPasswordEncoder */ @Bean public BCryptPasswordEncoder passwordEncoder() { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); return bCryptPasswordEncoder; } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/signup") .permitAll() .antMatchers("/**") //.hasAnyRole("ADMIN", "USER") .hasRole("USER") .anyRequest() .authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/login") .usernameParameter("username") .passwordParameter("password") .defaultSuccessUrl("/index", true) .failureUrl("/login?error") .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login?logout") .permitAll(); } @Autowired public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); } }
AuthService .java @Service public class AuthService implements UserDetailsService { @Autowired private AuthMapper loginMapper; @Autowired private BCryptPasswordEncoder passwordEncoder; /** * パスワードハッシュ化 * @return BCryptPasswordEncoder */ @Bean public BCryptPasswordEncoder passwordEncoder() { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); return bCryptPasswordEncoder; } @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { AccountEntity user = loginMapper.selectLoginUser(userName); if (user == null || "".equals(userName)) { throw new UsernameNotFoundException("ユーザー" + userName + "登録されていないか、無効なアカウントです"); } boolean debugEnabled =user.isEnabled(); System.out.println("########################"); System.out.println(debugEnabled); System.out.println("########################"); String debugRole = user.getRole(); System.out.println("########################"); System.out.println(debugRole); System.out.println("########################"); List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>(); GrantedAuthority authority = new SimpleGrantedAuthority(user.getRole().toString()); grantList.add(authority); UserDetails userDetails = (UserDetails) new User(user.getUsername(), user.getPassword(), grantList); System.out.println("########################"); System.out.println(userDetails); System.out.println("########################"); return userDetails; } }
AccountEntity.java /** * * @author hiromune mochida * @version 2021/01/18 * アカウントエンティティクラス * */ @Data public class AccountEntity implements UserDetails { private final long serialVersionUID = 1L; /** 権限の種類 */ //TODO 削除予定 public enum Authority { ROLE_USER, ROLE_ADMIN } /** ユーザーネーム */ private String userName; /** パスワード */ private String password; /** 有効判定 */ //private boolean enabled; /** 権限 */ //private Authority role; private String role; /** 削除フラグ */ private String delFlg; /** コンストラクタ */ public AccountEntity(String userName, String password) { this.userName = userName; this.password = password; //this.enabled = true; this.role = "ROLE_USER"; this.delFlg = "0"; //TODO 削除予定 //this.role = Authority.ROLE_USER; } public AccountEntity() { } /** ユーザーに与えられている権限リストを返却する */ @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority(this.role.toString())); return authorities; } /** ユーザー名を返却する */ @Override public String getUsername() { return userName; } /** アカウントの有効期限の状態を判定する */ @Override public boolean isAccountNonExpired() { return true; } /** アカウントのロック状態を判定する */ @Override public boolean isAccountNonLocked() { return true; } /** 資格情報の有効期限の状態を判定する */ @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
AuthMapper.java /** * * @author hiromune mochida * @version 2021/01/18 * ログインマッパークラス */ @Mapper public interface AuthMapper { /** * ログイン情報取得 * @param userName * @param password * @return AccountEntity */ public AccountEntity selectLoginUser(String userName); }
AuthController.java /** * ユーザー認証用コントローラークラス * @author hiromune mochida * @version 2021/01/16 */ @Controller public class AuthController { /** * ログイン画面表示 * @return String */ @GetMapping("/login") public String getLogin() { return "auth/login"; } /** * 入力情報送信 * @return String */ @PostMapping("/login") public String postLogin() { return "redirect:auth/index"; } /** * ログアウト * @return String */ @PostMapping("/logout") public String logout() { return "redirect:auth/login"; } //TODO 適切なフォルダに移動予定 @GetMapping("/index") public String index() { return "auth/index"; } }
AuthMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.tsuika.mapper.AuthMapper"> <select id="selectLoginUser" resultType="com.example.tsuika.entity.AccountEntity"> select act.user_name ,act.password ,act.role from account act where act.user_name = #{userName} </select> </mapper>
login.html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>tsuika</title> </head> <body> <form th:action="@{/login}" method="post"> <h2>Login</h2> <input class="form" type="text" name="username" placeholder="ユーザー名" /> <input class="form" type="password" name="password" placeholder="パスワード" /> <button class="" type="submit">ログイン</button> </form> </body> </html>
index.html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h2>index</h2> </body> </html>
//アカウントテーブル作成 create table tsuika.account( user_name VARCHAR (255) NOT NULL comment 'ユーザー名' , password VARCHAR (255) NOT NULL comment 'パスワード' , role VARCHAR (10) comment '権限名' , created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP comment '作成日時' , updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP comment '更新日時' , del_flg char (1) default '0' comment '削除フラグ' , PRIMARY KEY (user_name) ) default charset = utf8 comment = 'アカウント';
試したこと
マッパー.xmlとマッパー.javaのパッケージ構成を合わせる。
例)src/main/java/com/example/tsuika/mapper
src/main/resouces/com/example/tsuika/mapper
値が取得できているかSystem.out.printlnでデバッグ致しました。
補足情報(FW/ツールのバージョンなど)
Spring boot 2.4.2
mybatis-spring-boot-starter 2.1.4
java 1.8
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。