6

Spring Security には、認証がプリンシパルであるという前提があります。

public interface Authentication extends Principal, Serializable {}

HttpServletRequest には、プリンシパル オブジェクトへのアクセスを担当するgetUserPrincipalのメソッドがあります。

このケースを考えてみましょう:

public interface RealPrincipal extends Principal {
   public Integer getId();
}

共通モジュール A には、Real Principal インターフェイスと実装があります。

モジュール A は、共通モジュール A、サーブレット API を使用し、Spring Security に依存しません。

モジュール B は、共通モジュール A、サーブレット Api を使用し、Spring Security を構成します。このモジュールは、セキュリティと UserDetails の実装を担当します。

Web A はモジュール A とモジュール B を使用します。

リクエスト メソッドを使用するために、次のような実装になります。

public ModelAndView someRequestHandler(Principal principal) {
   User activeUser = (User) ((Authentication) principal).getPrincipal();
   ...
}

これにより、モジュール A およびその他のモジュールの Spring Security に依存する必要があります。適切なサーブレット API の抽象化は、Spring セキュリティに依存すべきではないと考えています。request.getUserPrincipal は実際のプリンシパルを返す必要があります。

org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper が返される理由を説明してください

の代わりに認証Real Principal

編集:共通モジュール A をシナリオに追加し、モジュール B がセキュリティを担当することを更新しました。

4

2 に答える 2

5

Luke が述べたように、Spring Security はプリンシパルを実装しているため、プリンシパルに認証を使用します。Authentication#getPrincipal() はプリンシパルであることが保証されていない (オブジェクトである) ため、使用しません。実際、ほとんどの場合、Spring Security の Authentication#getPrincipal() は User (プリンシパルを実装していません)、フレームワークのユーザーによって提供されるカスタム UserDetails、または String を返します。

Spring Security でこれを処理する場合は、Luke が提案したように HttpServletRequestWrapper を使用してこのロジックを実装する必要がある可能性があります。たとえば、次のことができます。

public RealPrincipalFilter extends OncePerRequestFilter {

    public void doFiter(HttpServletRequest request, HttpServletResponse response, FilterChain) {
        chain.doFilter(new RealPrincipalRequestWrapper(request), response);
    }

    private static final class RealPrincipalRequestWrapper 
          extends HttpServletRequestWrapper {
        public Principal getUserPrincipal() {
            Authentication auth = (Authentication) super.getPrincipal();
            return auth == null ? null : (RealPrincipal) auth.getPrincipal()
        }
    }
}

@Configuration
@EnableWebSecurity
public WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public configure(HttpSecurity http) {
        http
            // ... other config ...
            .addFilterAfter(new RealPrincipalFilter(), SecurityContextHolderAwareRequestFilter.class);
    }
    ...
}

または、Spring MVC と統合するためのオプションについて、他の質問に対する私の回答をご覧ください - Spring Security によるコントローラーへのカスタム プリンシパルの注入

于 2013-07-19T16:50:23.530 に答える
1

簡単な答えはAuthenticationPrincipalそれを必要とするAPI(あなたが言及したサーブレットAPIメソッドなど)で使用できるようにするためです。

これは実際にはどういう意味ですか?多くはありません。Java のPrincipalインターフェースにはメソッドが 1 つしかないgetNameため、ユーザーの名前をレンダリングする以上のことをしたい場合は、実装についてもっと知る必要があります。

「本当のプリンシパル」と「適切なサーブレット API の抽象化」というフレーズを使用する場合、おそらく何を意味するのかを考えておく必要があります。someRequestHandlerたとえば、プリンシパルが「実際の」ものである場合、メソッドをどのように実装すると予想されますか?

于 2013-07-19T11:04:20.820 に答える