Como auditar quando um usuário deixa um aplicativo ASP.NET

No asp.net, estou procurando uma maneira de auditar um usuário deixando meu aplicativo. Para ser específico, gostaria de inserir um registro de 'logout' em uma tabela de auditoria no SQL Server quando a sessão do usuário for abandonada/destruída por qualquer motivo (não necessariamente por causa de uma chamada para session.abandon)

Eu tenho uma classe 'SessionHelper' que gerencia os setters/getters de sessão.

Eu tentei postar de volta em Session_End no Global.asax, mas ele nunca disparou esse evento mesmo depois que o tempo limite expirou.

Eu tentei substituir 'finalize' na classe SessionHelper e fazê-lo lá quando a classe é destruída, mas também não disparou esse evento.

Eu tentaria implementar IDisposable no SessionHelper, mas não sei onde chamá-lo para que ele sempre seja chamado.

Qual é a maneira correta de auditar um usuário deixando seu aplicativo ASP.NET?

Obrigado!

2

3 Respostas

O evento Session_End é acionado apenas se você tiver sessões InProc. O gerenciamento de sessões do SQL ou do servidor de estado não disparará este evento. Se você puder, volte para as sessões InProc e use este evento.

Além disso, você não obterá soluções muito boas. O ASP.NET não oferece uma maneira de ver a lista atual de sessões no servidor (pelo menos, como os usuários do StackOverflow sabem, já que eu já fiz a pergunta), então você não pode usar um trabalho para verifique quando eles são destruídos.

A próxima melhor coisa seria ter um "último horário de acesso" armazenado em algum lugar para seus usuários e usá-lo para detectar um tempo limite da sessão. A implementação de tal tarefa é complicada (você pode perder eventos de logout se um usuário fizer logon/logout rapidamente, por exemplo) ...

Portanto, não há solução perfeita aqui.

2
adicionado

Note com certeza sobre o "caminho certo", mas aqui está como eu fiz isso no passado.

Ter um carimbo de data/hora "ativo" associado ao registro do usuário no banco de dados. Toda vez que o usuário acessa uma página, isso é atualizado para a hora atual. Se alguém não tiver acessado a página em, digamos, 15 minutos, esse usuário será registrado como um evento de "logout" e o registro de data e hora será definido como NULL.

2
adicionado
Eu faço algo semelhante, eu uso manipulação de sessão baseada em sql e tenho uma última coluna acessada na tabela segurando meus dados de sessão. Existe um proc armazenado que é executado toda vez que um registro de sessão é modificado, o que limpa as tabelas de qualquer linha de sessão não utilizada inativa por mais tempo do que um valor TIMEOUT predefinido.
adicionado o autor stephenbayer, fonte

Na melhor das hipóteses, seu registro de logout será um palpite inteligente, mesmo se você fizer com que os eventos da sessão funcionem corretamente, de quando o usuário saiu do seu site/aplicativo. Uma técnica que você pode usar é colocar o tempo de logout no banco de dados quando o usuário efetua login e apenas atualiza o registro futuramente à medida que eles usam o sistema. Aqui está o esquema geral de uma tabela de sessão que usei recentemente:

[Id]  [Uid]    [LoginInOn]        [ExpiresOn]  
 1    johndoe  10/14/2008 10:47   10/14/2008 11:07  

Nesta tabela, continuo atualizando a coluna ExpiresOn enquanto o usuário interage com o aplicativo (tempo atual + 20 minutos). Se eles tentarem interagir depois do ExpiresOn, então eu sei que eles ficaram inativos por 20 minutos e forçaram um novo login. Para fins de relatório, sei que o usuário fez logout se a hora atual for maior que ExpiresOn. Você pode ficar mais complexo que isso. Por exemplo, eu movo meus dados da tabela de sessões listados acima para uma tabela de relatórios com um processo regular. Isso é apenas para manter a tabela de sessões pequena, já que muita coisa interage com ela.

1
adicionado