私が無知の為、大変ご面倒おかけしますが、力を貸して下さい。
実現したいこと
SpringSecurityを使用して、同じログイン画面でform認証とGoogle OAuth2認証を併用したいです。
起こっている問題
Google OAuth2認証はログイン出来、画面遷移するが、form認証を行うと、以下のエラーメッセージが現れてログインが出来ない。
ErrorMessage
java.lang.IllegalStateException: Current user principal is not of type [org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken]: UsernamePasswordAuthenticationToken [Principal=com.test.main.AuthUserDetails@62f854e2, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=9793C4B6FBC9D3FA656F567410ED74E3], Granted Authorities=[USER]] at org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.resolveArgument(ServletRequestMethodArgumentResolver.java:169) ~[spring-webmvc-5.3.13.jar:5.3.13] at org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.resolveArgument(ServletRequestMethodArgumentResolver.java:124) ~[spring-webmvc-5.3.13.jar:5.3.13] at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.13.jar:5.3.13]
エラーが出ている該当のソースコード
Java:AuthUserDetails.java
package com.test.main; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class AuthUserDetails implements UserDetails { private AuthEntity auth; private Collection<GrantedAuthority> authorities; public AuthUserDetails() {} public AuthUserDetails(AuthEntity auth, Collection<GrantedAuthority> authorities) { this.auth = auth; this.authorities = authorities; } ←ここでエラー発生 @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.authorities; } @Override public String getPassword() { return auth.getPassword(); } @Override public String getUsername() { return auth.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
関係があると思っているソースコード
HTML:login.html
略 <body> <div> <div> <form action="#" th:action="@{/login}" method="post" th:object="${loginForm}" id="loginF"> <input type="text" id="username" name="username" placeholder="メールアドレス" /> <input type="password" id="password" name="password" placeholder="パスワード" /> <button type = "submit"> </form> <div> <a th:href="@{/oauth2/authorization/google}" class="anchor"><span>Googleアカウントでログイン</span></a> </div> </div> </div> </body> </html>
Java:DbSecurityConfig.java
package com.test.main; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.firewall.DefaultHttpFirewall; import com.komesuku.main.model.service.AuthAccountService; @EnableWebSecurity public class DbSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthAccountService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override public void configure(WebSecurity web) { DefaultHttpFirewall firewall = new DefaultHttpFirewall(); web.httpFirewall(firewall); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/css/**", "/png/**", "/js/**", "/regist", "/forgot", "/message", "/registPass", "/registPassDone", "/reYesterday").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login").permitAll() .defaultSuccessUrl("/success",true) .and() .oauth2Login() .loginPage("/login").permitAll() .defaultSuccessUrl("/success",true) .and() .logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll(); http.requiresChannel().anyRequest().requiresSecure(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } }
Java:AuthAccountService.java
package com.test.main.model.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; import com.komesuku.main.AuthEntity; import com.komesuku.main.AuthMapper; import com.komesuku.main.AuthUserDetails; @Service public class AuthAccountService implements UserDetailsService { @Autowired private AuthMapper mapper; @Autowired JdbcTemplate jdbcTemplate; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if(ObjectUtils.isEmpty(username)) { throw new UsernameNotFoundException("ユーザー名を入力してください"); } AuthEntity auth = mapper.findByUsername(username); if(auth == null) { throw new UsernameNotFoundException("ユーザーが見つかりません"); } return new AuthUserDetails(auth, AuthorityUtils.createAuthorityList("USER")); } }
Java:AuthEntity.java
package com.test.main; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import lombok.Data; @Data public class AuthEntity { public AuthEntity(String username, String password) { this.username = username; this.password = password; } @NotBlank(message="必須項目です") @Size(max=50,message="必須項目です") private String username; @NotBlank(message="必須項目です") @Size(max=100,message="必須項目です") private String password; }
試した事
・エラーメッセージより、form認証がGoogle OAuth認証だと判断されている為、Webセキュリティコンフィグに@Orderを設置し順番を指定した
→ 結果同じエラー
参考資料
・第4回:Spring Security 5でサポートされたOAuth 2.0 Loginの動作をカスタマイズしてみる
https://qiita.com/kazuki43zoo/items/53804e18337933a77ad0#%E7%8B%AC%E8%87%AA%E8%AA%8D%E8%A8%BC%E3%81%A8oauth-20-login%E6%A9%9F%E8%83%BD%E3%81%AE%E4%BD%B5%E7%94%A8
・Spring Security 使い方メモ 認証・認可
https://qiita.com/opengl-8080/items/032ed0fa27a239bdc1cc
どうかよろしくお願い致します。
まだ回答がついていません
会員登録して回答してみよう