16

背景認証ゲートウェイ

としてZuulを使用して、私はこのarticleで提示設計を実装します。

以下の図で要​​約することができます。クライアントは最初のIDPが無いユーザ情報とアクセストークン(不透明なトークンを返しIDP(OpenIDの接続/のOAuth2)

  • で認証 Security Architecture

    1. クライアントはAPIゲートウェイ経由で呼び出します。認証ヘッダーのアクセストークンを使用します。
    2. APIゲートウェイは、アクセストークンを使用してIDPに要求します。
    3. IDPは、アクセストークンが有効であることを確認し、JSON形式
    4. API Gatewayは、JWTにユーザー情報を保存し、秘密鍵で署名してユーザー情報を返します。サービスが要求
    の認証および認可となって、それに沿って、それはJWTを渡す要求を満たすために別のサービスを呼び出す必要がある場合はJWTは、その後
  • 公開鍵を使ってJWTを検証し、下流サービスに渡されます私が持っているもの

    これまでのところ、私はそれのほとんどが使用して行われてい

    • 春クラウドをグローバルな枠組みとして
    • APIゲートウェイ

    として、個々のサービスに

  • NetflixのZuulを起動する
  • 春ブーツ私はまた、アクセストークンをチェックZuul PREフィルタを書か連絡先IDPとJWTを作成しています。 JWTは、下流のサービスに転送された要求のヘッダーに追加されます。

    問題は今、私の質問はZuulとそのフィルタに非常に固有のものです。何らかの理由でAPIゲートウェイで認証が失敗した場合、フィルタチェーンを継続して通話を転送せずに、ルーティングを停止して401で直接応答できますか?現時点で

    認証フィルタは、ヘッダにJWTを追加しませんし、401は下流サービスから来る失敗した場合。私のゲートウェイがこの不必要な呼び出しを防ぐことができることを望んでいました。

    私はこれを行うにはcom.netflix.zuul.context.RequestContextを使用することができます方法を確認しようとしましたが、ドキュメントは非常に悪く、私は方法を見つけることができませんでした。

  • +0

    この問題を解決するのだろうか?それはafaikのためにこれをすぐに提供します。 –

    +0

    @ M.Deinum私はこの特定のデザインを実装するのに十分なコントロールができないと思いました。私はセキュリティで保護されたネットワークとJWTの外でアクセストークンを持っている必要があります。私はSpring Cloudのセキュリティに関する多くの経験がありません。あなたは私のデザインを達成するためにそれを使うことができると思いますか? – phoenix7360

    +0

    Spring Cloud Securityは、同じトークンをダウンストリーム・サービスにのみ中継します。 @ phoenix7360のようなトークンを交換したり強化したりする能力はありません。しかし、それは妥当なビルディングブロックです。 –

    答えて

    9

    あなたは現在のコンテキストでsetSendZuulResponse(false)を設定してみてください可能性があります。これはリクエストをルーティングすべきではありません。文脈からremoveRouteHost()を呼び出すこともできます。これは同じことを達成します。 setResponseStatusCodeを使用して401ステータスコードを設定することができます。

    0

    私は答えが非常に遅いと知っています あなたはzuulのプレフィルターでアプローチすることができます。あなたが従わなければならないステップは以下の通りです。

    //1. create filter with type pre 
    //2. Set the order of filter to greater than 5 because we need to run our filter after preDecoration filter of zuul. 
    @Component 
    public class CustomPreZuulFilter extends ZuulFilter { 
    
        private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
    
    @Override 
    public Object run() { 
        final RequestContext requestContext = RequestContext.getCurrentContext(); 
        logger.info("in zuul filter " + requestContext.getRequest().getRequestURI()); 
        byte[] encoded; 
        try { 
         encoded = Base64.encode("fooClientIdPassword:secret".getBytes("UTF-8")); 
         requestContext.addZuulRequestHeader("Authorization", "Basic " + new String(encoded)); 
    
         final HttpServletRequest req = requestContext.getRequest(); 
         if (requestContext.getRequest().getHeader("Authorization") == null 
           && !req.getContextPath().contains("login")) { 
          requestContext.unset(); 
          requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); 
    
         } else { 
           //next logic 
          } 
         } 
    
        } catch (final UnsupportedEncodingException e) { 
         logger.error("Error occured in pre filter", e); 
        } 
    
        return null; 
    } 
    
    
    
    @Override 
    public boolean shouldFilter() { 
        return true; 
    } 
    
    @Override 
    public int filterOrder() { 
        return 6; 
    } 
    
    @Override 
    public String filterType() { 
        return "pre"; 
    } 
    
    } 
    

    requestContext.unset()現在のスレッドのアクティブ要求のRequestContextをリセットします。応答ステータスコードを提供することができます。

    3

    があなたのrunメソッド内で次を追加します。あなたはこのために春のクラウドセキュリティを使用していないなぜ、それが

    ctx.setSendZuulResponse(false); 
    ctx.setResponseStatusCode(401); 
    
    関連する問題