1. Обзор
В этом кратком руководстве мы покажем, как мы можем добавить функцию выхода из системы в приложение безопасности OAuth Spring .
Мы, конечно, будем использовать приложение OAuth, описанное в предыдущей статье, – создание REST API с помощью OAuth2 .
Примечание : в этой статье используется устаревший проект Spring OAuth . Для версии этой статьи, использующей новый стек Spring Security 5, ознакомьтесь с нашей статьей Выход из защищенного приложения OAuth .
2. Удалите маркер доступа
Проще говоря, выход из системы в среде, защищенной OAuth, включает в себя вывод маркера доступа пользователя недействительным -поэтому он больше не может использоваться.
В реализации на основе JdbcTokenStore- это означает удаление токена из TokenStore .
Давайте реализуем операцию удаления для токена. Мы собираемся использовать здесь основную структуру /oauth/token URL и просто ввести для нее новую операцию УДАЛЕНИЯ.
Теперь, поскольку мы на самом деле используем /oauth/токен URI здесь – нам нужно обращаться с ним осторожно. Мы не сможем просто добавить это к любому контроллеру – потому что фреймворк уже имеет операции, сопоставленные с этим 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. Удалите маркер обновления
В предыдущей статье , посвященной Обработке маркера обновления , мы настроили наше приложение так, чтобы оно могло обновлять маркер доступа с помощью маркера обновления. Эта реализация использует прокси – сервер Zuul-с CustomPostZuulFilter для добавления значения refresh_token , полученного с Сервера авторизации, в файл cookie refreshToken .
При отмене маркера доступа, как показано в предыдущем разделе, связанный с ним маркер обновления также становится недействительным. Однако файл HttpOnly cookie останется установленным на клиенте, учитывая, что мы не можем удалить его с помощью JavaScript, поэтому нам нужно удалить его со стороны сервера.
Давайте улучшим реализацию CustomPostZuulFilter , которая перехватывает /oauth/token/revoke URL, чтобы удалить refreshToken cookie при обнаружении этого 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
Помимо отзыва токена доступа из хранилища токенов, файл cookie access_token также должен быть удален со стороны клиента.
Давайте добавим метод в наш контроллер AngularJS , который очищает файл cookie access_token и вызывает сопоставление /oauth/token/revoke DELETE:
$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"); } ); }
Эта функция будет вызвана при нажатии на ссылку Выход из системы :
5. Заключение
В этом быстром, но подробном уроке мы показали, как мы можем выйти из системы пользователя из OAuth защищенное приложение и аннулирует токены этого пользователя.
Полный исходный код примеров можно найти на GitHub .