1. ホーム
  2. java

[解決済み] Spring BootとSpring SecurityでREST APIを保護するには?

2023-05-09 11:35:13

質問

REST APIのセキュリティ確保は広くコメントされている話題ですが、私の基準を満たす小さなプロトタイプを作ることができません(そして、これらの基準が現実的であることを確認する必要があります)。リソースを保護する方法とSpringセキュリティで動作する方法は非常に多くのオプションがありますが、私のニーズが現実的であるかどうかを明確にする必要があります。

私の要求

  • トークンベースの認証システム - ユーザーは認証情報を提供し、ユニークで時間制限のあるアクセストークンを取得します。トークンの作成、有効性のチェック、有効期限を自分の実装で管理したい。
  • いくつかのRESTリソースは公開されます - 認証は全く必要ありません。
  • 一部のリソースは、管理者権限を持つユーザーのみがアクセスできるようになります。
  • その他のリソースは、すべてのユーザーが承認後にアクセスできるようになります。
  • ベーシック認証は使用しない
  • Javaコードの設定 (XMLではない)

現在の状態

私の REST API は非常によく機能しますが、現在それを保護する必要があります。私が解決策を探していたとき、私は javax.servlet.Filter フィルタを作成しました。

  @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
        Account account = accountDao.find(accessToken);

        if (account == null) {    
            throw new UnauthorizedException();    
        }

        chain.doFilter(req, res);

    }

しかし、この解決策では javax.servlet.filters による例外処理に問題があるため、この解決策は私が必要とするようには機能しません。 @ControllerAdvice を使った例外処理に問題があるからです。 servlet dispatcher .

必要なもの

私はこれらの基準が現実的であるかどうかを知り、Spring SecurityでREST APIを保護することを開始する方法について、何か助けを得たいと思います。私は多くのチュートリアルを読みました(例えば Spring Data REST + Spring Security ) を読みましたが、すべて非常に基本的な構成で動作します - ユーザーが の認証情報はメモリに保存されます。 を持つユーザーはメモリに保存され、私はDBMSと連動し、独自の認証機能を作成する必要があります。

どのように始めるか、私にいくつかのアイデアを与えてください。

どのように解決するのですか?

<ブロッククオート

トークンベースの認証 - ユーザーは認証情報を提供し、一意の期間限定アクセストークンを取得します。 一意の期間限定アクセストークンを取得します。私は、トークンの作成、有効性の確認、有効期限を独自の実装で管理したいと思います。 作成、有効性のチェック、有効期限を管理したいです。

実はトークンAuthにFilterを使うのが一番良い方法です。

最終的にはSpring DataでCRUDを作成し、Tokenのプロパティ(有効期限など)を管理します。

以下は私のトークンフィルタです。 http://pastebin.com/13WWpLq2

そして、トークンサービスの実装

http://pastebin.com/dUYM555E

<ブロッククオート

一部のRESTリソースは公開される - 認証は全く必要ない

問題ありません。このようにSpringのセキュリティ設定によってリソースを管理することができます。 .antMatchers("/rest/blabla/**").permitAll()

一部のリソースは、管理者権限を持つユーザーのみがアクセスできるようになります。

を見てみましょう。 @Secured アノテーションをクラスに追加します。例

@Controller
@RequestMapping(value = "/adminservice")
@Secured("ROLE_ADMIN")
public class AdminServiceController {

もう一方のリソースは、全ユーザーの認証後にアクセスできるようになります。

Spring Securityの設定に戻りますが、このようにurlを設定することができます。

    http
            .authorizeRequests()
            .antMatchers("/openforall/**").permitAll()
            .antMatchers("/alsoopen/**").permitAll()
            .anyRequest().authenticated()

ベーシック認証は使いたくない

トークン・フィルタを使えば、ユーザーは認証されます。

<ブロッククオート

Javaコードの設定(XMLではありません)

上の言葉に戻って @EnableWebSecurity . あなたのクラスは、次のようになります。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

をオーバーライドする必要があります。 configure メソッドをオーバーライドする必要があります。以下のコードは、マッチャーを設定する方法の一例です。これは別のプロジェクトからのものです。

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/assets/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .loginPage("/login")
                .defaultSuccessUrl("/", true)
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
                .logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .and()
                .csrf();
}