Logout em um aplicativo protegido OAuth
1. Visão geral
Neste tutorial rápido, vamos mostrar como podemosadd logout functionality to an OAuth Spring Security application.
Obviamente, usaremos o aplicativo OAuth descrito em um artigo anterior -Creating a REST API with OAuth2.
2. Remova o token de acesso
Simplificando, o logout em um ambiente protegido por OAuth envolverendering the user’s Access Token invalid - portanto, não pode mais ser usado.
Em uma implementação baseada emJdbcTokenStore-, isso significa remover o token deTokenStore.
Vamos implementar uma operação de exclusão para o token. Vamos usar a estrutura de URL parimary/oauth/token aqui e simplesmente introduzir uma nova operação DELETE para ela.
Agora, porque na verdade estamos usando o URI/oauth/token aqui - precisamos lidar com isso com cuidado. Não seremos capazes de simplesmente adicionar isso a qualquer controlador - porque o framework já tem operações mapeadas para esse URI - com POST e GET.
Em vez disso, o que precisamos fazer é definir este é um@FrameworkEndpoint – para que seja captado e resolvido peloFrameworkEndpointHandlerMapping em vez doRequestMappingHandlerMapping padrão. Dessa forma, não teremos nenhuma partida parcial e não teremos nenhum conflito:
@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);
}
}
}
Observe como estamos extraindo o token da solicitação, simplesmente usando o cabeçalhoAuthorization padrão.
3. Remova o token de atualização
Em um artigo anterior sobreHandling the Refresh Token, configuramos nosso aplicativo para ser capaz de atualizar o token de acesso, usando um token de atualização. Esta implementação usa um proxy Zuul - comCustomPostZuulFilter para adicionar o valorrefresh_token recebido do servidor de autorização a um cookierefreshToken.
Ao revogar o token de acesso, conforme mostrado na seção anterior, o token de atualização associado a ele também é invalidado. No entanto, o cookiehttpOnly permanecerá definido no cliente, visto que não podemos removê-lo via JavaScript - portanto, precisamos removê-lo do lado do servidor.
Vamos aprimorar a implementação deCustomPostZuulFilter que intercepta o URL/oauth/token/revoke para remover o cookierefreshToken ao encontrar este 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. Remova o token de acesso do cliente AngularJS
Além de revogar o token de acesso do armazenamento de tokens, o cookieaccess_token também precisará ser removido do lado do cliente.
Vamos adicionar um método ao nosso controladorAngularJS que limpa o cookieaccess_token e chama o mapeamento 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");
}
);
}
Esta função será chamada ao clicar no linkLogout:
5. Conclusão
Neste tutorial rápido, mas aprofundado, mostramos como podemos desconectar um usuário de um aplicativo seguroOAuth e invalidar os tokens desse usuário.
O código-fonte completo dos exemplos pode ser encontradoover on GitHub.