2013-02-06 5 views
21

Spring 3でRESTfulなWebサービスを開発しており、/webservices/login/<username>/<password>//webservices/logoutのようなログイン/ログアウトの機能が必要です。セッションは、セッションがタイムアウトになるか、他のWebサービスを消費するためにログアウトするまで、コンテキストに格納する必要があります。セッション情報なしでWebサービスにアクセスする要求はすべて拒否されます。このシナリオの最先端のソリューションを探しています。Spring 3のRESTでのログイン/ログアウト

私は実際に質問Spring Security 3 programmatically loginに質問しましたが、まだ正しく回答されていません。 web.xmlにも必要な変更を指定してください。

+7

私は強くURLにパスワードまたはユーザー名を入力しないことをお勧めします。それらは仲介者によって記録され、履歴に保存されます。代わりに、HTTP基本認証(もちろんSSL経由)のような既存のメカニズムを使用します。これはHTTPのネイティブ機能を使用する「RESTful」な方法です。 (私はSpring Securityの使用法については話すことができません) – dbreaux

+0

この記事では、標準のSpring Securityを使用してRESTと従来の認証を簡単に設定する方法について説明します。 [春のセキュリティのajaxログイン](http://stackoverflow.com/questions/4912485/spring-security-ajax-login/16577637#16577637) – SergeyB

答えて

50

あなたのSpring Securityフィルターを完全に手動で定義することをお勧めします。これは難しいことではなく、ログイン/ログアウトの動作を完全に制御できます。 (あなたは3うたサーブレットAPI上にない場合は、サポート非同期を削除する)すべての

まず、あなたは春に、フィルタ・チェーンの処理を委任するために、標準のweb.xml宣伝文が必要になります。

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <async-supported>true</async-supported> 
    <filter-class> 
     org.springframework.web.filter.DelegatingFilterProxy 
    </filter-class> 
</filter> 



<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

さて、セキュリティにコンテキストでは、パスごとにフィルタを個別に定義します。フィルタは、上記のXMLは、フィルタチェーンを介して特定のコンテキスト相対URLへの要求を渡すために春を告げる

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> 
    <sec:filter-chain-map path-type="ant"> 
     <sec:filter-chain pattern="/login" filters="sif,wsFilter"/> 
     <sec:filter-chain pattern="/logout" filters="sif,logoutFilter" /> 
     <sec:filter-chain pattern="/rest/**" filters="sif,fsi"/> 
    </sec:filter-chain-map> 
</bean> 

など、ユーザーを認証したユーザをログアウト、セキュリティ資格情報を確認することができます。フィルタチェーンの中の最初のものはセキュリティコンテキストを確立しています - 'sif' beanはそれを処理します。チェーンの

<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> 

次フィルタは、今のいずれか(読み:ユーザーをログアウト/ログイン)セキュリティコンテキストにデータを追加することができ、またはを判断をするかどうかに基づいてアクセスを許可するセキュリティコンテキストは語りました。

あなたが要求から認証データを読み込み、フィルタをお勧めします、あなたのログインURLの場合

は、それを検証し、ターン店でそれ(セッションに保存されている)のセキュリティコンテキストで:

<bean id="wsFilter" class="my.own.security.AuthenticationFilter"> 
    <property name="authenticationManager" ref="authenticationManager"/> 
    <property name="authenticationSuccessHandler" ref="myAuthSuccessHandler"/> 
    <property name="passwordParameter" value="pass"></property> 
    <property name="usernameParameter" value="user"></property> 
    <property name="postOnly" value="false"></property> 

私は独自の実装を使用している理由は、フィルタチェーン処理を継続することです(デフォルトの実装では、認証が成功したときにリダイレクトされ、フィルタチェーンが終了すると仮定しています) 、そして毎回ユーザー名とパスワードが渡され、認証処理することができること:あなたがHTTP基本認証ヘッダーを使用して認証など/ログインパスのための独自のフィルタの実装、任意の数を追加することができます

public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 

@Override 
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { 
    return (StringUtils.hasText(obtainUsername(request)) && StringUtils.hasText(obtainPassword(request))); 
} 

@Override 
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, 
     Authentication authResult) throws IOException, ServletException{ 
    super.successfulAuthentication(request, response, chain, authResult); 
    chain.doFilter(request, response); 
} 

を、ヘッダダイジェストリクエスト本体からusername/pwdを抽出することさえできます。 Springはそのためのフィルタ群を提供しています。

私はデフォルトのリダイレクト戦略を上書きします私自身の認証成功のハンドラがあります。[OK]をしている場合は(だけでなく、おそらくカスタム認証フィルタ)カスタム認証成功ハンドラを持っている必要はありません

public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 

    @PostConstruct 
    public void afterPropertiesSet() { 
     setRedirectStrategy(new NoRedirectStrategy()); 
    } 

    protected class NoRedirectStrategy implements RedirectStrategy { 

     @Override 
     public void sendRedirect(HttpServletRequest request, 
       HttpServletResponse response, String url) throws IOException { 
      // no redirect 

     } 

    } 

} 

をユーザーでログイン成功後にリダイレクトされる(、URLをカスタマイズすることができ、チェックのドキュメントをリダイレクト)

は、ユーザーの詳細情報を取得するための責任を負うことになります認証マネージャを定義します。

<sec:authentication-manager alias="authenticationManager"> 
    <sec:authentication-provider ref="myAuthAuthProvider"/> 
</sec:authentication-manager> 

<bean id="myAuthAuthProvider" 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="myUserDetailsImpl"/> 
     </bean> 
    </property> 
</bean> 

ここで独自のユーザー詳細Bean実装を提供する必要があります。

ログアウトフィルタ:あなたは

<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> 
    <property name="authenticationManager" ref="myAuthenticationManager"/> 
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/> 
    <property name="securityMetadataSource"> 
     <sec:filter-invocation-definition-source> 
      <sec:intercept-url pattern="/rest/**" access="ROLE_REST"/> 
     </sec:filter-invocation-definition-source> 
    </property> 
</bean> 

必要があります。

<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> 
    <property name="allowIfAllAbstainDecisions" value="false"/> 
    <property name="decisionVoters"> 
     <list> 
      <ref bean="roleVoter"/> 
     </list> 
    </property> 
</bean> 

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/> 

<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/> 

アクセス制御フィルタ(自明でなければなりません):

<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
    <constructor-arg> 
     <list> 
      <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 
     </list> 
    </constructor-arg> 
</bean> 

一般的な認証のものをセキュリティコンテキストをクリアする責任@Secured aでRESTサービスを確保することもできますメソッドのnnotations。

上記のコンテキストは、既存のRESTサービスwebapp-sorryから抜け出しました。

secスプリングタグを使用して、ここで実装されているものの少なくともほとんどを行うこともできますが、私はカスタムコントロールを優先します。

これは少なくともあなたを始めます。

+1

この説得力と詳細な答えをありがとうございます。 – FKhan

+0

ユーザーをログアウトするためにログアウトURLを呼び出す方法を教えてください。 – Franklin

+1

@Franklin、springSecurityFilterChainのパス定義に注意してください。path/logoutはセキュリティコンテキストをクリアし、ユーザをログアウトするlogoutFilterを呼び出すように設定されています。 – rootkit

関連する問題