Выйти из приложения с защитой 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.