1. 概要

この記事では、SpringSecurityで認証するためのカスタムデータベースベースのUserDetailsServiceを作成する方法を示します。

2. UserDetailsService

UserDetailsService インターフェースは、ユーザー関連のデータを取得するために使用されます。 loadUserByUsername()という名前のメソッドが1つあり、これをオーバーライドして、ユーザーを見つけるプロセスをカスタマイズできます。

DaoAuthenticationProvider が、認証中にユーザーに関する詳細をロードするために使用します。

3. ユーザーモデル

ユーザーを保存するために、データベーステーブルにマップされるUserエンティティを次の属性で作成します。

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    private String password;

    // standard getters and setters
}

4. ユーザーの取得

ユーザー名に関連付けられたユーザーを取得するために、 JpaRepository インターフェイスを拡張して、 SpringDataを使用してDAOクラスを作成します。

public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);
}

5. UserDetailsService

独自のユーザーサービスを提供するには、UserDetailsServiceインターフェイスを実装する必要があります。

インターフェイスのメソッドloadUserByUsername()をオーバーライドするMyUserDetailsServiceというクラスを作成します。

このメソッドでは、DAOを使用してUserオブジェクトを取得し、存在する場合は、UserDetails[を実装するMyUserPrincipalオブジェクトにラップします。 X175X]、そしてそれを返します:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return new MyUserPrincipal(user);
    }
}

MyUserPrincipalクラスを次のように定義しましょう。

public class MyUserPrincipal implements UserDetails {
    private User user;

    public MyUserPrincipal(User user) {
        this.user = user;
    }
    //...
}

6. スプリング構成

カスタムUserDetailsService実装を使用するために必要な、XMLとアノテーションベースの両方のタイプのSpring構成を示します。

6.1. 注釈の構成

カスタムUserDetailsServiceを有効にするために必要なのは、それをBeanとしてアプリケーションコンテキストに追加することだけです。

@Service アノテーションを使用してクラスを構成したため、アプリケーションはコンポーネントスキャン中に自動的にそれを検出し、このクラスからBeanを作成します。 したがって、ここで行う必要のあることは他にありません。

または、次のこともできます。

  • AuthenticationManagerBuilder#userDetailsService メソッドを使用して、authenticationManagerで構成します
  • カスタムauthenticationProvider Beanのプロパティとして設定し、 AuthenticationManagerBuilder#authenticationProvider関数を使用してそれを挿入します

6.2. XML構成

一方、XML構成の場合、タイプ MyUserDetailsService のBeanを定義し、それをSpringのauthentication-providerBeanに注入する必要があります。

<bean id="myUserDetailsService" 
  class="org.baeldung.security.MyUserDetailsService"/>

<security:authentication-manager>
    <security:authentication-provider 
      user-service-ref="myUserDetailsService" >
        <security:password-encoder ref="passwordEncoder">
        </security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>
    
<bean id="passwordEncoder" 
  class="org.springframework.security
  .crypto.bcrypt.BCryptPasswordEncoder">
    <constructor-arg value="11"/>
</bean>

7. その他のデータベースに基づく認証オプション

AuthenticationManagerBuilder は、アプリケーションでJDBCベースの認証を構成するためのもう1つの方法を提供します。

AuthenticationManagerBuilder.jdbcAuthenticationDataSourceインスタンスで構成する必要があります。 データベースがSpringUser Schema に従っている場合は、デフォルトの構成が適しています。

以前の投稿で、このアプローチを使用した基本的な構成を見てきました。

この構成の結果であるJdbcUserDetailsManagerエンティティは、UserDetailsServiceも実装します。

その結果、特に DataSource を自動的に構成するSpring Bootを使用している場合は、この構成の実装が簡単であると結論付けることができます。

とにかく、より高いレベルの柔軟性が必要で、アプリケーションがユーザーの詳細を取得する方法を正確にカスタマイズする必要がある場合は、このチュートリアルで従ったアプローチを選択します。

8. 結論

要約すると、この記事では、永続データに基づくカスタムのSpringベースのUserDetailsServiceを作成する方法を示しました。

実装はGitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。