5
Help us understand the problem. What are the problem?

posted at

SpringSecurity5.7にアップデートしたらUserDetailsServiceを用いた認可ができなくなった

前提

SpringSecurity5.7から書き方が大きく変わります!

詳細は以下の公式ブログにて解説がありますが、
WebSecurityConfigurerAdapter@deprecatedになります。

以下の記事もお世話になりました。

困ったこと

もともとUserDetailsServiceを用いてDBに登録されているユーザーを認可していたのがSpringSecurity5.7以降でできなくなりました。

before

SecurityConfig.java
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = passwordEncoder();
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }
}

WebSecurityConfigurerAdapter@deprecatedのため使用するのは好ましくないですし、
そもそも実行できません。(以下のエラーが出ます。)

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  securityConfig (field private org.springframework.security.core.userdetails.UserDetailsService com.example.config.SecurityConfig.userDetailsService)
↑     ↓
|  inMemoryUserDetailsManager defined in class path resource [org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.class]
└─────┘

解決策

JdbcUserDetailsManagerを使うように修正(というか作り直し?)しました。

m_userはユーザー情報が入ったテーブルです。
デフォルトでは、テーブル名がUSERSAUTHORITIESと固定になっています。
別の名前のテーブルから認可情報を取得したい場合は以下のように記述すると記載の情報を用いて認可を行ってくれます。

SecurityConfig.java
@EnableWebSecurity
@Configuration
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsManager users(DataSource dataSource) {
        String userQuery =
                "select user_id,password,true from m_user where user_id = ?";
        String authoritiesQuery =
                "select user_id,role from m_user where user_id = ?";
        JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
        users.setUsersByUsernameQuery(userQuery);
        users.setAuthoritiesByUsernameQuery(authoritiesQuery);
        return users;
    }
}

いつか誰かの役に立てば幸いです!!!

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
5
Help us understand the problem. What are the problem?