SpringBootとSpringSecurityでRESTAPIを保護する方法は?


80

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

私の要件

  • トークンベースのオーセンティケーター-ユーザーはその資格情報を提供し、一意で時間制限のあるアクセストークンを取得します。トークンの作成、有効性の確認、有効期限を自分の実装で管理したいと思います。
  • 一部のRESTリソースは公開されます-認証する必要はまったくありません、
  • 一部のリソースには、管理者権限を持つユーザーのみがアクセスできます。
  • 他のリソースは、すべてのユーザーの承認後にアクセスできるようになります。
  • 基本認証を使いたくない
  • Javaコード構成(XMLではない)

現在の状態

私のRESTAPIは非常にうまく機能しますが、今度はそれを保護する必要があります。解決策を探していたときに、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);

    }

しかし、Springjavax.servlet.filtersを介した例外処理に問題があるため、このソリューションは必要に応じて機能しません。@ControllerAdviceservlet dispatcher

必要なもの

これらの基準が現実的であるかどうかを知り、助けが得られるかどうか、SpringSecurityでRESTAPIの保護を開始する方法を知りたいです。多くのチュートリアル(Spring Data REST + Spring Securityなど)を読みましたが、すべて非常に基本的な構成で機能します。資格情報を持つユーザーは構成のメモリ保存されるため、DBMSを使用して独自のオーセンティケーターを作成する必要があります。

始め方のアイデアを教えてください。

回答:


67

トークンベースの認証-ユーザーはその資格情報を提供し、一意で時間制限のあるアクセストークンを取得します。トークンの作成、有効性の確認、有効期限を自分の実装で管理したいと思います。

実際には、トークン認証にフィルターを使用します-この場合の最良の方法

最終的には、Spring Dataを介してCRUDを作成し、有効期限などのトークンのプロパティを管理できます。

これが私のトークンフィルターです: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 configureに戻ると、次のように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();
}

私の質問で私を助けてくれませんか?stackoverflow.com/questions/46065063/…–
Felipe A.

2
すべての要件を含むプロジェクトの例はありますか?
AlikElzin-kilaka 2018

@Oleksandr:ロングショットですが、RESTAuthenticationTokenProcessingFilterクラスのupdateLastLogin(...)メソッドでスレッドを開始した理由を教えてください。
Z3d4s

1
@ z3d4s、実際には古い例(4年)です。今のところ、OffsetDateTime、別のアプローチなどを使用することをお勧めします:)保存中に追加の時間がかかる可能性があるため、ユーザーリクエストの処理時間を短縮するために使用することを提案した新しいスレッドデータベースに。
OleksandrLoushkin19年

ああ、なるほど、それは天才的な解決策です!ありがとう!
Z3d4s

4

Springセキュリティは、RESTURLに認証と承認を提供するのにも非常に役立ちます。カスタム実装を指定する必要はありません。

まず、以下のように、セキュリティ構成でrestAuthenticationEntryPointへのentry-point-refを指定する必要があります。

 <security:http pattern="/api/**" entry-point-ref="restAuthenticationEntryPoint" use-expressions="true" auto-config="true" create-session="stateless" >

    <security:intercept-url pattern="/api/userList" access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/api/managerList" access="hasRole('ROLE_ADMIN')"/>
    <security:custom-filter ref="preAuthFilter" position="PRE_AUTH_FILTER"/>
</security:http>

restAuthenticationEntryPointの実装は次のようになります。

 @Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

   public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException ) throws IOException {
      response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
   }
}

この後、RequestHeaderAuthenticationFilterを指定する必要があります。RequestHeaderキーが含まれています。これは基本的にユーザーの認証を識別するために使用されます。通常、RequestHeaderは、REST呼び出しを行うときにこの情報を伝達します。たとえば、以下のコードを検討してください

   <bean id="preAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="Authorization"/>
    <property name="authenticationManager" ref="authenticationManager" />
  </bean>

ここに、

<property name="principalRequestHeader" value="Authorization"/>

「承認」は、着信要求を提示するキーです。必要なユーザーの認証情報を保持します。また、要件を満たすようにPreAuthenticatedAuthenticationProviderを構成する必要があります。

   <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
  <bean id="userDetailsServiceWrapper"
      class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
    <property name="userDetailsService" ref="authenticationService"/>
  </bean>
</property>
</bean>

このコードは、カスタム実装なしで認証と承認によってRESTURLを保護するために機能します。

完全なコードについては、以下のリンクを見つけてください。

https://github.com/srinivas1918/spring-rest-security



-1

REST APIを検証するには、2つの方法があります

1-application.propertiesファイルで設定されたデフォルトのユーザー名とパスワードを使用した基本認証

基本認証

2-実際のユーザー名とパスワードでデータベース(userDetailsS​​ervice)を使用して認証します

高度な認証


ビデオは便利です。ReSTAPIに対して同じ高度な認証を行う方法。ここでは、Webについてのみ説明します。RESTAPIの高度な認証に関するビデオチュートリアルはありますか?
ジェイコブ

2番目のビデオ(高度な認証)を見た場合は、RESTクライアント(REST API用)を使用して同じ認証を行っています。
jeet singh parmar 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.