Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Autorização páginas/componentes de acordo com perfil de acesso e Modelo de Autenticação

Boa tarde, estou começando agora a desenvolver para web no padrão RestFull, desenvolvia para a web somente com JSF.

Gostaria de ter uma ideia de como é feito:

A autenticação baseada em token por exemplo, terei de enviar toda vez no cabeçalho da requisição e lá na API ter um filtro que verifica toda vez se o token é válido realizando a consulta na base dados para validar o acesso? Ou o token é armazenado em sessão no servidor e no filtro verifico a validade na sessão ao invés de consultar no banco?

A autorização de rotas para paginas por perfil de acesso? (Se é Perfil 1 pode acessar tal, tal e tal rota, Se é Perfil 2 pode acessar tal, tal e tal rota)

6 respostas

Tudo fica no token...as permissões. ..e a cada requisição ele deve ser enviado, descriptografado pela sua api e testado. Deu server fica stateless, não há sessão.

Acho que entendi a parte de autenticação ... Faço o login acessando o recurso e é devolvido um token com todas as informações, armazeno no lado client e toda requisição eu envio no cabeçalho, sendo que no filtro eu descriptografo e testo a validade do token e com a informação do perfil de acesso contido tbm no token ele autoriza ou não o acesso ao recurso através das rules por perfil (pode ser usado o picketlink ou spring security pra isso certo?)

Com relação a autorização das rotas que não ta muito claro, vamos supor um cenario,

Tenho um usuário com perfil ADM que pode acessar as paginas 1, 2 e 3, e um outro usuário OPERADOR que pode acessar somente a pagina 1. Vamos supor que o usuário OPERADOR digita diretamente no navegador a URL da rota da página 3 e ele só pode acessar a página 1. Como que é feita essa "autorização de rota" ? Tem q validar tudo no lado client (vue.js), tipo descriptografar o token, pegar o perfil de acesso e fazer os testes para cada Rota x Perfil ?

Se você querer ter um controle no lado do Vue, quando você autenticar o usuário, além de enviar o token você envia um objeto com as permissões desse usuário. Tanto o token quanto esse objeto você precisará persistir no browser. Dai, sua aplicação Vue acessa esse objeto e escolhe o que deseja exibir, por exemplo, usando v-show.

Tem alguns que perguntam: ah, mas se o usuário alterar o objeto com as permissões? Se ele fizer isso, terá acesso há outras partes da app, mas não há problema algum nisso porque todas as operações são validadas baseada no token dele, que guarda a mesmo informação criptograda.

solução!

O lance das rotas no front-end resolvi mais ou menos assim:


export const routes = [
**Outras rotas**
    { path: '/gerenciar-usuarios', component: load('GerenciarUsuarios'), name: 'gerenciarUsuarios', meta: { requireAuth: true, grantAll: false, grants: ['ADMINISTRADOR_SISTEMA'] } },
    { path: '/itens-cardapio', component: load('ItensCardapio'), name: 'itensCardapio', meta: { requireAuth: true, grantAll: false, grants: ['ADMINISTRADOR_ESTABELECIMENTO'] } },
    { path: '/painel-pedidos', component: load('PainelPedidos'), name: 'painelPedidos', meta: { requireAuth: true, grantAll: false, grants: ['ADMINISTRADOR_ESTABELECIMENTO', 'OPERADOR_ESTABELECIMENTO'] } },
    { path: '*', component: load('Error404'), name: 'error404', meta: { requireAuth: false } } 

]


const router = new VueRouter({
    routes,
    mode: 'history'

});

router.beforeEach((to, from, next) => {

    if (to.meta.requireAuth) {

        const authToken = LocalStorage.get.item('auth-token');
        const userAuth = LocalStorage.get.item('userAuth');

        if ((authToken && to.meta.grantAll) || (authToken && to.meta.grants.includes(userAuth.perfil))) {

            console.log('Grant all: ' + to.meta.grantAll);
            console.log('Grants: ' + to.meta.grants);

            next();

        } else {

            if (authToken && !to.meta.grants.includes(userAuth.perfil)) {
                next({ name: 'error404' });
            } else {
                next({ name: 'login' });
            }

        }

    } else {
        next();
    }
});

A parte dos menus resolvi com v-if pegando perfil do usuario pelo LocalStorage tbm.

Agora uma dúvida, toda requisição eu devo descriptografar o token no back-end e fazer uma consulta na base de dados para validar? Não tem outra maneira que não utilize tanto a base de dados e consiga resolver este problema que não seja armazenando em memória (map, por exemplo)?

Outra coisa é uma sugestão de framework de segurança, na primeira postagem mencionei o picketlink e o spring security. Qual dos dois é mais fácil de implementar ? Tem algum esquema em um desses de só anotar com a Enum e o proprio framework validar(tipo @Secured(PerfilUsuario.ADMIN)?

"Agora uma dúvida, toda requisição eu devo descriptografar o token no back-end e fazer uma consulta na base de dados para validar? " Sim. Se o token tiver tudo q você precisa nem precisa ir no banco.

Sobre essas tecnologias javas não sei informar.

Acho que a dúvida maior é onde eu armazeno e como valido esse token no backend.

Se eu não verificar a existência do token em memória em um Map por exemplo, não ir na base buscar o token em alguma tabela, como eu consigo verificar as informações só com o token enviado?

Penso que preciso descriptografar o token no back-end e fazer as validações necessárias a cada requisição:

  • Caso o token esteja armazenado em memória (Map), buscar pela chave "token" no mapa e pegar a senha no objeto do usuario que é a chave da assinatura no caso.

  • Caso seja na base de dados, fazer um select toda vez que uma requisição for realizada, pra verificar se esse token existe na base e ai pegar os dados do usuário para descriptografar o token e validar as permissões.

Caso não seja armazenado em lugar nenhum (Banco ou memória) qualquer token não passaria na validação?