Logout em um aplicativo protegido OAuth

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.