質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Java

    14093questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring Boot

    532questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • ログイン

    120questions

    ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Spring Boot 認証機能の「A UserDetailsService must be set」エラーについて

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 819

omou

score 6

SpringBoot で認証機能を実装しようと試みているのですが、コンパイル時に以下エラーが発生しており困っています。

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
~省略~
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userAuthenticationFilter': Unsatisfied dependency expressed through method 'setAuthenticationManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationManager' defined in class path resource [org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Factory method 'authenticationManager' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDaoAuthenticationProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoAuthenticationProvider' defined in file [D:\13_eclipseProject\GanttChart\bin\com\omoumou\gantt\web\login\UserDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:644) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:89) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
~省略~
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationManager' defined in class path resource [org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Factory method 'authenticationManager' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDaoAuthenticationProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoAuthenticationProvider' defined in file [D:\13_eclipseProject\GanttChart\bin\com\omoumou\gantt\web\login\UserDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set
~省略~
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Factory method 'authenticationManager' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDaoAuthenticationProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoAuthenticationProvider' defined in file [D:\13_eclipseProject\GanttChart\bin\com\omoumou\gantt\web\login\UserDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:182) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:575) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    ... 41 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDaoAuthenticationProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoAuthenticationProvider' defined in file [D:\13_eclipseProject\GanttChart\bin\com\omoumou\gantt\web\login\UserDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set
~省略~
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoAuthenticationProvider' defined in file [D:\13_eclipseProject\GanttChart\bin\com\omoumou\gantt\web\login\UserDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1717) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
~省略~
Caused by: java.lang.IllegalArgumentException: A UserDetailsService must be set
    at org.springframework.util.Assert.notNull(Assert.java:193) ~[spring-core-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.doAfterPropertiesSet(DaoAuthenticationProvider.java:105) ~[spring-security-core-5.0.0.M2.jar:na]
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.afterPropertiesSet(AbstractUserDetailsAuthenticationProvider.java:123) ~[spring-security-core-5.0.0.M2.jar:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1713) ~[spring-beans-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    ... 82 common frames omitted

エラーの原因は
UserDaoAuthenticationProviderクラスにUserDetailServiceを実装したクラスをAutowiredしていないため発生しているものなのかと思ったのですが、修正しても同じエラーが発生してしまいます。

以下原因と思われるクラスのソースです。

@Component
public class UserDaoAuthenticationProvider extends DaoAuthenticationProvider {

    private static final Logger logger = LoggerFactory.getLogger(UserDaoAuthenticationProvider.class);

    @Autowired
    UserMapper userMapper;

    // これを追加してもダメ
    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        super.additionalAuthenticationChecks(userDetails, authentication);

        UserAuthenticationToken companyIdUsernamePasswordAuthentication = (UserAuthenticationToken) authentication;
        String requestedCompanyId = companyIdUsernamePasswordAuthentication.getTeamId();
        String companyId = ((LoginUser) userDetails).getUser().getTeamId();

        if (!companyId.equals(requestedCompanyId)) {
            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials",
                    "Bad credentials"));
        }
    }

    @Override
    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        String companyId = ((LoginUser) user).getUser().getTeamId();
        return new UserAuthenticationToken(user, authentication.getCredentials(), companyId, user.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> token) {
        logger.info("supports");
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(token);
    }


}

他に必要な情報があれば追記させていただきます。
お手数をおかけしますが宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

check解決した方法

0

原因は不明ですがとりあえず解決しましたので展開させていただきます。(本当は解決方法をしっかり判明させて書き込みたかったのですが、私には無理でした。。)

スーパークラス「DaoAuthenticationProvider」の下記メソッドが実行されるタイミングで「this.userDetailsService」がnullなためエラーが発生していたみたいです。

protected void doAfterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
    }

質問文で記載している自作クラス「UserDaoAuthenticationProvider」で、上記メソッドをOverrideするとエラーは発生しなくなり、コンパイルが通る様になりました。

@Override
protected void doAfterPropertiesSet() throws Exception {}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Springに精通している訳ではないのですが、もし解決されたらと思い回答します。

@autowiredをつけたクラスはインタンス管理をSpringに移譲することになるので、Spring管理されるために@Compornentが必要だと認識してました。

また、@Compornentをつけるだけではなく、Springにそのクラスを認識させるために、メインクラスのパッケージ配下に@Compornentをつけたクラスを格納するか、@ComopornentScanを付与したクラスが所属するパッケージ配下に属さなければならないと記憶してます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/24 11:52

    ご回答ありがとうございます。

    すみません。
    私のソース転記ミスです。。
    @Componentは上記クラス「UserDaoAuthenticationProvider」にちゃんと記述しており、上位のパッケージのクラスにも@SpringBootApplication(これは@ComponentScanの機能も含んでいる認識です。)を記述しております。

    キャンセル

0

UserDaoAuthenticationProviderに複数の

@Autowired
UserDetailsService UserDetailsService;

があるようですが、これは誤記でしょうか。

ちなみにAutowiredで取得しているUserDetailsServiceのインスタンス(規約的にはserDetailsServiceとするのが良いでしょう)が、UserDaoAuthenticationProviderのどのメソッドからも利用されていませんが、これは必要なのでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/24 21:59

    ご回答ありがとうございます。
    すみません。複数Autowiredしてしまっているのは誤記ですね。。。実際は一つです。

    UserDetailsServiceを使用していないのにAutowiredしている意図についてですが、
    エラー文の中に「UserDetailsService must be set」という文言が記載されており、使用していなくてもUserDetailsServiceをAutowiredする必要があるのかも?という考えで追記していました。
    (記憶が定かではないのですが、過去に同じエラーが発生した際に同じ対応をして復旧したことがあったような気がしたので。。)


    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    14093questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring Boot

    532questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • ログイン

    120questions

    ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。