1. 概要

このクイックチュートリアルでは、 OAuthSpringSecurityアプリケーションにログアウト機能を追加する方法を紹介します。

もちろん、前の記事で説明したOAuthアプリケーション– OAuth2を使用したRESTAPIの作成を使用します。

:この記事ではSpringOAuthレガシープロジェクトを使用しています。 新しいSpringSecurity5スタックを使用したこの記事のバージョンについては、記事OAuth保護アプリケーションでのログアウトをご覧ください。

2. アクセストークンを削除する

簡単に言うと、OAuthで保護された環境でログアウトするには、ユーザーのアクセストークンを無効にするが必要になるため、使用できなくなります。

JdbcTokenStore- ベースの実装では、これはTokenStoreからトークンを削除することを意味します。

トークンの削除操作を実装しましょう。 ここでは、予備の / oauth / token URL構造を使用し、新しいDELETE操作を導入します。

ここでは実際に/oauth / token URIを使用しているため、慎重に処理する必要があります。 フレームワークにはPOSTとGETを使用して、そのURIにマップされた操作がすでにあるため、これをコントローラーに単純に追加することはできません。

代わりに、これを @FrameworkEndpoint – と定義して、標準のRequestMappingHandlerMappingではなくFrameworkEndpointHandlerMappingによって取得および解決されるようにする必要があります。 そうすれば、部分的な一致に遭遇したり、競合が発生したりすることはありません。

@FrameworkEndpoint
public class RevokeTokenEndpoint {

    @Resource(name = "tokenServices")
    ConsumerTokenServices tokenServices;

    @RequestMapping(method = RequestMethod.DELETE, value = "/oauth/token")
    @ResponseBody
    public void revokeToken(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        if (authorization != null && authorization.contains("Bearer")){
            String tokenId = authorization.substring("Bearer".length()+1);
            tokenServices.revokeToken(tokenId);
        }
    }
}

標準のAuthorizationヘッダーを使用して、リクエストからトークンを抽出していることに注目してください。

3. 更新トークンを削除します

更新トークンの処理に関する前回の記事では、更新トークンを使用してアクセストークンを更新できるようにアプリケーションを設定しました。 この実装では、Zuulプロキシを使用します– CustomPostZuulFilter を使用して、認証サーバーから受信したrefresh_token値をrefreshTokenCookieに追加します。

前のセクションで示したように、アクセストークンを取り消すと、それに関連付けられている更新トークンも無効になります。 ただし、JavaScriptを介して削除できないため、 httpOnly Cookieはクライアントに設定されたままになるため、サーバー側から削除する必要があります。

/ oauth / token / revokeURLをインターセプトするCustomPostZuulFilter実装を拡張して、このURLに遭遇したときに refreshTokenCookieを削除するようにしましょう。

@Component
public class CustomPostZuulFilter extends ZuulFilter {
    //...
    @Override
    public Object run() {
        //...
        String requestMethod = ctx.getRequest().getMethod();
        if (requestURI.contains("oauth/token") && requestMethod.equals("DELETE")) {
            Cookie cookie = new Cookie("refreshToken", "");
            cookie.setMaxAge(0);
            cookie.setPath(ctx.getRequest().getContextPath() + "/oauth/token");
            ctx.getResponse().addCookie(cookie);
        }
        //...
    }
}

4. AngularJSクライアントからアクセストークンを削除します

トークンストアからアクセストークンを取り消すだけでなく、 access_tokencookieもクライアント側から削除する必要があります。

AngleJS コントローラーに、 access_token cookieをクリアし、 / oauth / token / revokeDELETEマッピングを呼び出すメソッドを追加しましょう。

$scope.logout = function() {
    logout($scope.loginData);
}
function logout(params) {
    var req = {
        method: 'DELETE',
        url: "oauth/token"
    }
    $http(req).then(
        function(data){
            $cookies.remove("access_token");
            window.location.href="login";
        },function(){
            console.log("error");
        }
    );
}

この関数は、ログアウトリンクをクリックすると呼び出されます。

<a class="btn btn-info" href="#" ng-click="logout()">Logout</a>

5. 結論

この迅速で詳細なチュートリアルでは、 OAuth で保護されたアプリケーションからユーザーをログアウトし、そのユーザーのトークンを無効にする方法を示しました。

例の完全なソースコードは、GitHubにあります。