Выйти из приложения с защитой OAuth

Выйти из приложения с защитой OAuth

1. обзор

В этом кратком руководстве мы покажем, как мы можемadd logout functionality to an OAuth Spring Security application.

Разумеется, мы будем использовать приложение OAuth, описанное в предыдущей статье -Creating a REST API with OAuth2.

2. Удалить токен доступа

Проще говоря, для выхода из среды, защищенной OAuth, требуетсяrendering the user’s Access Token invalid, поэтому его больше нельзя использовать.

В реализации на основеJdbcTokenStore- это означает удаление токена изTokenStore.

Давайте реализуем операцию удаления токена. Мы собираемся использовать здесь частичную структуру URL/oauth/token и просто ввести для нее новую операцию DELETE.

Теперь, поскольку мы на самом деле используем URI/oauth/token, нам нужно обращаться с ним осторожно. Мы не сможем просто добавить это к какому-либо контроллеру - потому что в платформе уже есть операции, сопоставленные с этим URI - с помощью POST и GET.

Вместо этого нам нужно определить, что это@FrameworkEndpoint –, чтобы его подбирал и разрешалFrameworkEndpointHandlerMapping вместо стандартногоRequestMappingHandlerMapping. Таким образом, у нас не будет неполных совпадений и конфликтов:

@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. Удалить токен обновления

В предыдущей статье оHandling the Refresh Token мы настроили наше приложение, чтобы оно могло обновлять токен доступа с помощью токена обновления. Эта реализация использует прокси Zuul - сCustomPostZuulFilter для добавления значенияrefresh_token, полученного от сервера авторизации, в файл cookierefreshToken.

При отзыве токена доступа, как показано в предыдущем разделе, связанный с ним токен обновления также становится недействительным. Однако файл cookiehttpOnly останется установленным на клиенте, поскольку мы не можем удалить его с помощью JavaScript, поэтому нам нужно удалить его на стороне сервера.

Давайте усовершенствуем реализациюCustomPostZuulFilter, которая перехватывает URL/oauth/token/revoke, чтобы она удаляла файл cookierefreshToken при обнаружении этого URL:

@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

Помимо отзыва токена доступа из хранилища токенов, файл cookieaccess_token также необходимо удалить со стороны клиента.

Давайте добавим к нашему контроллеруAngularJS метод, который очищает файл cookieaccess_token и вызывает отображение DELETE/oauth/token/revoke:

$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");
        }
    );
}

Эта функция будет вызываться при нажатии на ссылкуLogout:

5. Заключение

В этом быстром, но подробном руководстве мы показали, как можно выйти из защищенного приложенияOAuth и аннулировать токены этого пользователя.

Полный исходный код примеров можно найтиover on GitHub.