Déconnexion dans une application sécurisée OAuth

Déconnexion dans une application sécurisée OAuth

1. Vue d'ensemble

Dans ce rapide tutoriel, nous allons montrer comment nous pouvonsadd logout functionality to an OAuth Spring Security application.

Nous utiliserons bien sûr l’application OAuth décrite dans un article précédent -Creating a REST API with OAuth2.

2. Supprimer le jeton d'accès

En termes simples, la déconnexion dans un environnement sécurisé OAuth impliquerendering the user’s Access Token invalid - il ne peut donc plus être utilisé.

Dans une implémentation basée surJdbcTokenStore-, cela signifie supprimer le jeton desTokenStore.

Implémentons une opération de suppression pour le jeton. Nous allons utiliser ici la structure de l'URL du parimaire/oauth/tokenet introduire simplement une nouvelle opération DELETE.

Maintenant, parce que nous utilisons en fait l'URI de/oauth/token ici, nous devons le gérer avec soin. Nous ne pourrons pas simplement l'ajouter à un contrôleur - car le framework a déjà des opérations mappées sur cet URI - avec POST et GET.

Au lieu de cela, ce que nous devons faire est de définir ceci est un@FrameworkEndpoint – afin qu'il soit capté et résolu par lesFrameworkEndpointHandlerMapping au lieu desRequestMappingHandlerMapping standard. De cette façon, nous ne rencontrerons aucune correspondance partielle et nous n'aurons aucun conflit:

@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);
        }
    }
}

Remarquez comment nous extrayons le jeton de la requête, en utilisant simplement l'en-tête standardAuthorization.

3. Supprimer le jeton d'actualisation

Dans un article précédent surHandling the Refresh Token, nous avons configuré notre application pour pouvoir actualiser le jeton d'accès, en utilisant un jeton d'actualisation. Cette implémentation utilise un proxy Zuul - avec unCustomPostZuulFilter pour ajouter la valeurrefresh_token reçue du serveur d'autorisation à un cookierefreshToken.

Comme indiqué dans la section précédente, lors de la révocation du jeton d'accès, le jeton d'actualisation qui lui est associé est également invalidé. Cependant, le cookiehttpOnly restera défini sur le client, étant donné que nous ne pouvons pas le supprimer via JavaScript - nous devons donc le supprimer du côté serveur.

Améliorons l'implémentation deCustomPostZuulFilter qui intercepte l'URL de/oauth/token/revoke afin qu'elle supprime le cookierefreshToken lors de la rencontre de cette 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. Supprimer le jeton d'accès du client AngularJS

Outre la révocation du jeton d'accès du magasin de jetons, le cookieaccess_token devra également être supprimé du côté client.

Ajoutons une méthode à notre contrôleurAngularJS qui efface le cookieaccess_token et appelle le mappage DELETE de/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");
        }
    );
}

Cette fonction sera appelée en cliquant sur le lienLogout:

5. Conclusion

Dans ce didacticiel rapide mais détaillé, nous avons montré comment déconnecter un utilisateur d'une application sécuriséeOAuth et invalider les jetons de cet utilisateur.

Le code source complet des exemples peut être trouvéover on GitHub.