22

Spring Security を Web アプリケーションに統合しようとしています。認証と承認のプロセス全体を統合する限り、それは非常に簡単に思えます。

ただし、認証と承認の両方が非常に結びついているように見えるため、これらのプロセスを分割して、承認とは別に認証を取得する方法を理解するには、非常に時間がかかります。

認証プロセスはシステムの外部にあり (シングル サインオンに基づく)、これを変更することはできません。それでも、ユーザーがこのプロセスに成功すると、ロールを含めてセッションに読み込まれます。

私たちが達成しようとしているのは、Spring Security の承認プロセスにこの情報を利用することです。つまり、認証プロバイダーを介して取得するのではなく、ユーザー セッションからロールを取得するように強制します。

これを達成する方法はありますか?

4

7 に答える 7

24

認証が SSO サービスを使用して既に行われている場合は、Spring Security の事前認証フィルターのいずれかを使用する必要があります。次に、事前認証されたユーザー プリンシパルを使用して GrantedAuthority の

SpringSecurity には、J2eePreAuthenticatedProcessingFilter や RequestHeaderPreAuthenticatedProcessingFilter など、いくつかの事前認証フィルターが含まれています。SSO 実装がデータをリクエストのどこに詰め込むかを知っていれば、自分に合ったものを見つけることもできます。(もちろん、それは実装に依存します。)

Filterインターフェイスを実装し、doFilter メソッドで次のようにします。

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

    // principal is set in here as a header or parameter. you need to find out 
    // what it's named to extract it
    HttpServletRequest req = (HttpServletRequest) request; 

    if (SecurityContextHolder.getContext().getAuthentication() == null) {
        // in here, get your principal, and populate the auth object with 
        // the right authorities
        Authentication auth = doAuthentication(req); 
        SecurityContextHolder.getContext().setAuthentication(auth);
    }

    chain.doFilter(request, response);
}
于 2009-08-24T15:35:32.140 に答える
3

はい、可能です。Spring Security(Springの他のほとんどの部分と同様)はインターフェース駆動型であるため、フレームワークのさまざまな部分に対して独自の実装を選択的にプラグインできます。

更新: Springの承認メカニズムと認証メカニズムは連携して機能します。認証メカニズムはユーザーを認証GrantedAuthorityし、セキュリティコンテキストにさまざまなインスタンスを挿入します。次に、これらは承認機構によってチェックされ、特定の操作を許可/禁止します。

既存の認証の使用方法の詳細については、nontの回答を使用してください。もちろん、セッションから詳細を取得する方法(役割など)の詳細は、特定の設定によって異なります。ただしGrantedAuthority、SSOシステムによってセッションで事前入力されたロールから派生したインスタンスを配置すると、それらを認証ロジックで使用できるようになります。

リファレンスドキュメントから(私の強調で少し編集):

Spring Securityに基づかない認証システムとの相互運用性を提供するために、独自のフィルターまたはMVCコントローラーを作成できます(多くのユーザーが作成します)。たとえば、現在のユーザーをThreadLocalまたは JNDI場所から利用できるようにするコンテナ管理認証を使用している場合があります。または、従来の独自の認証システムを持っている会社で働いているかもしれません。これは、ほとんど制御できない企業の「標準」です。このような状況では、Spring Securityを機能させるのは非常に簡単であり、それでも認証機能を提供します。あなたがする必要があるのは、ある場所からサードパーティのユーザー情報を読み取り、Spring Security固有のAuthentication オブジェクトを作成し、それを SecurityContextHolder。これを行うのは非常に簡単で、完全にサポートされた統合アプローチです。

于 2009-08-24T13:08:41.290 に答える
2

認証を処理するサーバーは、何らかの種類のキー (CAS SSO のトークン) を渡すアプリケーションにユーザーをリダイレクトする必要があります。次に、アプリケーションはキーを使用して、関連付けられているユーザー名とロールを認証サーバーに要求します。この情報を使用して、承認マネージャーに渡されるセキュリティ コンテキストを作成します。これは、SSO ログイン ワークフローの非常に単純化されたバージョンです。CAS SSOCAS 2 アーキテクチャ
をご覧 ください。 さらに情報が必要な場合は教えてください。

于 2009-08-24T14:58:08.410 に答える
1

Spring Security の User オブジェクトは常にパスワードが入力されることを期待しており、シナリオではそれを気にしないため、独自の承認で CAS 認証を理解しようとしていますが、混乱していました。Surabh の投稿を読んだ後、秘訣はパスワードを入力せずにカスタム User オブジェクトを返すことのようです。それを試して、私のケースで機能するかどうかを確認します。チェーン内の他のコードが User オブジェクトのパスワードを期待していないことを願っています。

于 2010-02-18T16:36:19.747 に答える
1

認可目的でのみ春のセキュリティを使用しなければならなかったのと同じ要件がありました。認証には Siteminder を使用していました。Spring Security の承認部分を認証ではなく使用する方法の詳細については、http://codersatwork.wordpress.com/2010/02/13/use-spring-security-for-authorization-only-not-for-を参照してください。認証/

また、 http://code.google.com/p/spring-security-with-authorization-only/source/browse/にソース コードとテスト ケースを追加しました。

于 2010-02-17T17:07:37.670 に答える
1

I use the authorization by this:

  1. Inject the authorization related bean into my own bean:

    @Autowired
    private AccessDecisionManager    accessDecisionManager;
    @Autowired
    FilterSecurityInterceptor        filterSecurityInterceptor;
    
  2. Use this bean by this:

    FilterInvocation fi = new FilterInvocation(rundata.getRequest(), rundata.getResponse(), new FilterChain() {
    
        public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
            // TODO Auto-generated method stub
    
        }
    });
    FilterInvocationDefinitionSource objectDefinitionSource = filterSecurityInterceptor.getObjectDefinitionSource();
    ConfigAttributeDefinition attr = objectDefinitionSource.getAttributes(fi);
    Authentication authenticated = new Authentication() {
    
        ...........
    
        public GrantedAuthority[] getAuthorities() {
            GrantedAuthority[] result = new GrantedAuthority[1];
            result[0] = new GrantedAuthorityImpl("ROLE_USER");
            return result;
        }
    };
    accessDecisionManager.decide(authenticated, fi, attr);
    
于 2011-09-16T12:06:29.833 に答える