web-dev-qa-db-ja.com

Spring Boot OAuth2シングルサインオフ(ログアウト)

アプリケーションにOAuth2を使用することを検討しています。私が実装しようとしているアーキテクチャは次のとおりです。

  • 独自の(そしてこれだけの)承認サーバーがあります
  • 承認サーバーを使用してリソースへのアクセスを検証する一部のリソースアプリ
  • 認証のためにユーザーを認証サーバーにリダイレクトし、成功するとリソースアプリのAPIを消費する一部のクライアントアプリ(Web、モバイル)。

これまでのところ、3つの基本的なアプリ(1つの認証サーバー、1つのリソースサーバー、1つのクライアント)の間でこの相互作用を実装することができました。動作しないのはログアウト機能です。私は "悪名高いトリッキーな問題" を読みました。DaveSyerがチュートリアルで説明していますが、この場合、ユーザーはログアウト後に再ログインする必要があります。アクセストークンと更新トークンに数秒を与えようとしましたが、有効期限が切れると再度ログインするように求められる代わりに、クライアントアプリでNPEを取得しています。トークンストアからトークンを削除するために、この post で提案されている解決策も試しましたが、機能しません。シングルサインオフは、この実装の望ましい動作です。 Spring Boot Oauth2を使用してこれを達成するにはどうすればよいですか?何らかの理由で不可能な場合、Spring Bootを使用して集中型セキュリティを実装するために使用できる代替手段はどれですか?

前もって感謝します。

12

多くのテストの後、AuthServerにリダイレクトし、次のようにプログラムでログアウトするだけでこれを解決できることに気付きました。

  • クライアントアプリ(WebSecurityConfigurerAdapter):

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .logout()
                .logoutSuccessUrl("http://your-auth-server/exit");
    }
    
  • 許可サーバーで:

    @Controller
    public class LogoutController {
    
        @RequestMapping("/exit")
        public void exit(HttpServletRequest request, HttpServletResponse response) {
            // token can be revoked here if needed
            new SecurityContextLogoutHandler().logout(request, null, null);
            try {
                //sending back to client app
                response.sendRedirect(request.getHeader("referer"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

githubのサンプルアプリ をこの実装の完全な例とともに投稿しました。

17