O post de hoje vem com o objetivo de complementar dois posts do Edson Gonçalves referente Spring Security. Muitos desenvolvedores que pretende usar Spring Security (SS) em suas apps JEE para implementar a regra de segurança sofrem quando já temos dados cadastrado no BD e não queremos mudar as informações no BD para prefix o ROLE_ que é requerido pelo SS.
Neste post vou mostrar como resolver este problema, que você pode se deparar em sistema legado.
Vou levar em conta que você ja tem implementado o SS conforme este post do Edson Gonçalves. Caso contrário leia o post do Gonçalves antes de continuar com o meu.
Mas, para refrescar sua mente lembre-se que o role deve ter ROLE_ prefixado para que as regras funcionem. Isso é default no SS. Há como alterar, porém pesquisei muitooo e não conseguir implementar, no forum SS há varias sugestoes, mas nenhuma delas foi mais eficiente que prefix o ROLE_ com os dados trazido do BD.
Desenvolvendo
A solução é mais simples que podemos imaginar, você vai precisar apenas prefix o ROLE_. Para quem usa MySQL temos a funcao concat(), no Oracle podemos usar | | etc. Em verifique na documentação do seu banco como concatenar.
A seguir mostramos com o MySQL. É simples demais, confira:
authorities-by-username-query="SELECT username, concat('ROLE_',authority) FROM users where username = ? "
O código completo fica assim:
< jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT username, password, 'true' as enable FROM users WHERE username=?"
authorities-by-username-query="SELECT username, concat('ROLE_',authority) FROM users where username = ? "
/>
ou dessa forma:
users-by-username-query="SELECT l.login as username, l.senha as password, 'true' as enable from funcionario l where l.login=?"
authorities-by-username-query="SELECT lo.login as username, CONCAT('ROLE_',lo.cargo)as authority FROM funcionario lo where lo.login=?" />
Outra dica é se a coluna do usuario/password não for o que o Spring Security espera, basta você fazer conforme o código a seguir:
users-by-username-query="SELECT us.email as username, us.senha as password, 'true' as enable FROM usuario as us WHERE email=?"
authorities-by-username-query="SELECT us.email as username, us.tipo as authority FROM usuario us where email= ?"
Vou ficando por aqui, espero que tenham gostado do post.
olá Pessoal, eu nem sei por onde começar com este post. rs. Primeiro post que não sei o que escrever devido a emoção e a felicidade ao mesmo tempo. Mas, está ai mais um trabalho, a publicação do meu livro “Guia de bolso SCJP” assim foi que eu batizei hehe.
Sobre o Guia
Esse “filho” nasceu a partir de ter feito uma pequena analise e vi que alguns “candidatos SCJP” sentiam falta em saber o que de fato vai cair no exame, como se parece as perguntas? Muitos acreditam que veremos apenas : o código compila ou não?!. Porém, o exame ele vai muito além, vc deve saber porque não compila, porque lança à exceção Y e não X, qual o resultado correto (parece obvio ne? mas, o exame é expert em enganar o candidato ).
O outro motivo é que ele veio a partir da sala de aula dos cursos preparatório para SCJP que tenho ministrados, os alunos sempre perguntaram por que eu não lançava um livro da mesma forma que conduzia as aulas. Daí, acordei para vida e resolvi fazer essa “criança”. rs
Reunir minhas experiência de preparação para o exame de 10 meses( em 2007) + experiência com Java + o que conseguir aprender com a preparação + exame SCJP. Fora que “colei” tudo que ia identificando no meu exame e resolvi compartilhar no “guia”.
Outra razão foi que na época que estava estudando sentir falta de um livro que eu pudesse ler no ônibus, metrô, sala de espera, intervalo da faculdade etc. O livro da Kathy Sierra é um excelente livro, porem nao dar para ler ele em um metrô, pois quando estamos empolgados, temos que fechar o livro por alguma força maior e daí ficamos com uma leitura incompleta. Busquei no guia melhorar isso, não explicar a tecnologia Java em si, mas focar no exame, com pegadinhas, o que você deve ter no “sangue” para o exame e o que precisa ir para “decoreba”. Nisso criei capitulos curtos, porem ricos em conteúdo e que dar para ler em até 20 minutos e ainda manter-se atualizado e dando um refresh no cérebro sobre os assuntos que estão tendo mais dificuldades.
E antes que perguntem. O livro não substitui o livro da Kathy Sierra, pelo contrario ele vem como um material auxiliar. Ah outro detalhe, eu busquei usar uma linguagem não muito formal nas explanações para que o leitor acredite está conversando comigo. 🙂
Quem adquirir o livro, terá 6 mini-simulados (portugues e ingles) para poder brincar antes do exame real. Para adquirir o simulado, basta seguir os passos que estão nas primeiras páginas do Guia de Bolso
Se vc tem pressa e deseja adquirir o livro o mais rápido possivel e pode esperar a entrega por uma transpordora, pode ir até uma livraria Saraiva mais perto e adquirir um exemplar, veja onde fica a loja mais proxima: http://www.livrariasaraiva.com.br/inst/lojas_fisicas/
Agradecimentos
Quero agradecer a uma pessoa que ajudou bastante desde o contato com a editora até as revisões e dicas. O nosso famoso autor brasileiro Edson Gonçalves . O qual tenho uma grande admiração profissional e alem de ser um dos meus melhores amigos. Abraco e sucessso para você. Nem preciso dizer nada né?
E outro amigo o qual considero como irmao: Mario (Razec).
E uma pessoa que é outro amigo o Juliano Martins (meu ex-Arquiteto no projeto aqui na IBM). Tem uma colega de trabalho a Daniela Reis que deu uma força quando pensei em abandonar o barco. E ela acompanhou todo o processo bem do inicio mesmo, quase que seria a “mãe”.
Peço desculpas, por não colocar outros amigos, colegas, é que nesse momento não consigo pensar muito devido a sensação, emoçãovou esperar esse efeito passar e editar o post. Mas, agora está dificil.
Hoje vou apresentar um pequeno probleminha que alguns já passaram usando o hibernate. Porém, o problema não é do framework e sim do Eclipse que não importa os .jars quando este é adicionado usando library da própria IDE.A situação é bem simples: “o programador está convicto que tudo está OK, nao falta nenhum .jars, os imports correto etc.” Mas, ao executar aplicação e tentar salvar algo no BD, recebe uma exceção org.hibernate.Session.
Neste post vou mostrar aonde está o problema.
Lets go…
O problema
Como relatei o problema é na IDE Eclipse que ela nao faz os imports dos .jars que você adicionou ao projeto usando library. Que na verdade os .jars deveriam está na pasta lib do seu projeto fisicamente. Porém não é isso que acontece. Experimente ir na pasta lib do seu projeto e veja se vai ver algum .jar do hibernate. Acredito que não e por isso temos essa exceção em um caso como esse.
Abaixo olha os testes que e fiz e como solucionei (acredito que você já sabe como é):
Criei um projeto simples, que cadastra um cargo no BD. Somente para mostrar o problema.
Vamos felizes da vida tentar cadastrar uma novo cargo
Olha que beleza:
Vamos ver o que temos na pasta lib do meu projeto:
Bem, Não vejo meus arquivos .jars do hibernate que adicionei ao projeto. Onde estão sr. Eclipse? Esse é o problema do Eclipse, nos adicionamos os ,jars e ele nao copia fisicamente os .jars para a pasta lib. Isso dar certo quando é projeto não é JEE. Como falei neste post.
A solução, é copiar os .jars veja:
Agora vamos testar app novamente
Verificando no meu BD ver:
Pronto, resolvido o problema! Bem, Nem sempre a exceção com hibernate.session está relacionada com a falta dos .jars, as vezes é erro de programação mesmo. Mas, quando você está certo dos seus codes e está usando o Eclipse, não esqueça de ir a pasta lib do projeto e verificar se os .jars do Hibernate realmente estao no seu projeto.
Vou ficando por aqui, espero que a dica tenha ajudado quem está passando por essa situação, eu ja mandei uma nota para equipe do Eclipse, mas eles disseram que isso não é um bug da IDE. Bem, o NetBeans não tem isso, todas as libraries adicionadas ao projetos, temos os .jars fisicamente no projeto. Então, será que não é uma falha do nosso querido Eclipse? Eu ja reclamo disso desde da versão antes Galileo.
Hoje vou falar de um assunto que todos os desenvolvedores, arquitetos etc. tem que se preocupar ao desenvolver uma aplicação é a famosa segurança. Você como “profissional do software” tem que saber quem vai ter acesso a determinadas partes da sua aplicação e o que ele pode fazer após ter concedido o acesso.
Dizer se o usuário “camilo” for um simples “user” ele só pode navegar nas seguintes pages: “index.jsp, faleconosco.jsp etc”. Agora vamos dizer que o usuário “lopes” é um dos administradores do sistema, então ele pode acessar as páginas “cadastrarprodutos.jsp, deletarusuario.jsp que estão em /admin” etc.
Como fazer isso Camilo?
Bem, o objetivo deste post é dar um suporte quem está entrando agora no mundo JEE, hoje temos frameworks que ajudam de forma mais eficiente que usar Realm do TomCat. Mas, não pretendo ir além do Realm. Só ele dar um big post.
Alguns iniciantes em JavaEE, tem essa dúvida consigo: como implementar regra de acesso sem precisar fazer um hard-code?”
Fazer isso dentro do seu servlet, controller etc. não é boa ideia pelo simples motivo: “as regras de segurança podem mudar com bastante frequência”. Como por exemplo amanha você precisa adicionar um novo nível de administrador (sênior, pleno) e cada um com permissões diferentes. Mas, também pode acontecer de um novo grupo fazer parte da administração os “gerente de projetos” ai lá vai o desenvolvedor atualizar o code e se amanhã deixar de existir algum dos citados? Já viu o prolema que temos ao implementar regras de segurança dentro do seu servlet, controller etc.
Os iniciantes em JEE, põe tudo que for restrito dentro de WEB-INF, isso não é boa prática.
As regras de segurança referente acesso é algo que pode ser simples, mas também complexo, vai depender da regra de negócios da aplicação. Por exemplo, já vi aplicações que tem vários tipos de administradores, usuários, com acessos completamente diferentes, porém no mesmo nível. Mas, colocar em WEB-INF todos as suas pages .jsp. Vc deve se perguntar: “é seguro a quem?”.
Vamos parar de conversa e veremos na prática…
lets go…
Realm
Realm é um depósito de informações de usuário que autentica e autoriza os usuários.Usando realms, você põe a responsabilidade no servidor Web por obrigar a implementar políticas de segurança. Isto significa que os desenvolvedores não precisam escrever código para usar autenticação e autorização (não que isso os impeçam de fazê-lo). Delegando autenticação e autorização ao servidor, os desenvolvedores podem escrever códigos de propósitos gerais, sem preocupação com as regras de autorização de acesso. (Livro – Tomcat – Guia Rápido do Administrador)
Para esse exemplo vamos usar um dos mais populares container JEE o TomCat (versão 6). Se você estiver usando um container diferente, terá que ler a documentação do fabricante e saber como implementar. Porém há poucas mudanças na maioria das vezes.
TomCat 6 (se tiver a 5.x.x sem problemas, pode usar)
Aqui vamos implementar sem usar dados vindo do BD. Então veja como uma forma de praticar “Segurança” até porque sem BD, vc vai precisar sempre ficar atualizando o arquivo tomcat-users.xml e se você não usar criptografia, qualquer um pode abrir esse arquivo e saber as senhas de cada usuário.
Desenvolvendo
Crie um dynamic web project no Eclipse e deixe ele conforme a imagem a seguir. O meu chama RealmCamilo no decorrer do post, estarei informado o que teremos em cada page .jsp.
Na página acessonegado.jsp insira o código a seguir:
Agora vá no arquivo tomcat-users.xml no mesmo diretório do arquivo server.xml.
Nesse arquivo criamos os usuários que terão acesso aplicação e qual role ele pertence.
Não é muito difícil de ler, veja:
“lopes É-UM manager. Porém, admin e camilo são um manager e admin.”
O relacionamento aqui é one-to-many, nao se esqueça disso. Ou seja, um usuário pode ter mais de um nível de acesso.
Lembre-se isso ai só são strings. O poder deles está quando criamos as restrições no arquivo web.xml.
Criando as regras de acesso
Agora precisamos criar as regras de acesso, dizer o que um “manager” pode acessar e o que um “admin”pode acessar.
Abra o arquivo web.xml da sua aplicação.
Antes do primeiro código você precisa saber disso:
<security-constraint>: Protege um recurso, ou seja, diz o que será protegido e quem pode acessar.
<auth-constraint>: Isto especifica os roles que são permitidos acessar recursos cobertos por esta limitação de segurança.
<web-resource-collection>: sub-elemento de <security-constraint> que diz o que será registro.
<login-config>: diz qual o tipo de autenticação. Há quatros tipos: BASIC, DIGEST, FORM, SSL.
Para o nosso exemplo usaremos o FORM. O BASIC ele usa a caixa de autenticação do browser.
insira o código abaixo no seu arquivo web.xml
Atenção:
Agora tenha atenção com o código de <login-config> Muitos confundem, achando que se o login/senha estiver OK. Vá para a página que está em <form-login-page> , mas ali que temos nenhuma condição IF.
O segredo é que antes de ir para tela de login, vc precisa ter tentando acessar o conteúdo restrito(na realidade é isso que acontece, pense um pouquinho…), assim o servidor vai saber o que fazer com vc que acessar caso seu login/senha válido, ou seja, enviar você para a página que foi solicitada (requested).
Se você, tentar direto para página de login, sem tentar acessar um conteúdo restrito, como o servidor vai saber encaminha-lo? Já que no action do form não há nada que diz “vá para pagina XYZ”.
veja o código do form login.jsp
O atributo name, action deve ser com os nomes acima. Caso contrário, nada funciona como esperado. E nao esqueça que o método deve ser post, pois é um FORM.
Eu tenho o hábito de dizer: “Primeiro erre, para depois acertar”. Ou seja, primeiro tente acessar se não conseguir use seu login/senha. O máximo que vai receber é dizer que você não tem permissão para acessar.
Testando
*não esqueça dos starts/stops que você deve dar sempre que atualizar os arquivos .xml do tomcat.
Para testar vamos fazer um deploy da nossa app. Vamos usar um arquivo WAR, se não sabe como exportar um projeto como WAR veja no post indicado no inicio do post.
Abaixo como ficou minha exportação:
Veja meus teste de acesso:
Tentando com o usuário camilo
Resultado:
Tentando com o usuário lopes
Resultado:
Agora é com você
Experimente testar acessando o conteúdo restrito direto, tente colocar usuário inexistente, ou usuário com roles diferentes ao acesso permitido. E para ficar uma mensagem de erro personalizada, crie suas proprias páginas de erro.
Bom ficando por aqui, acho que este foi um dos maiores posts que já escrevi e nao sou a favor de posts grandes, mas foi necessário. O assunto precisava ser detalhado e olha que nao fui tanto assim. Vi vários outros posts na internet porém os que encontrei estava resumido demais e para quem está dando os primeiros passos pode se tornar complicado o processo. Espero que tenham gostado.
Nesse post veremos como criar um projeto Struts no Eclipse, veja como é bem simples ter um Struts Project usando o Jboss Tools. Se não tem o Jboss tools configurado no eclipse veja o “post relacionado”. O objetivo deste post é para quem está querendo dar os primeiros passos com Struts, porem nao sabe por onde começar.
Lets go…
Não irei abordar alguns conceitos tais como: vantagens, quando usar?, por que usar?. Na verdade isso daria um novo post. Para quem tiver interesse em saber mais sobre Struts podem dar uma olhada no link a seguir e também nas vagas de emprego para Java, tenho 99% de certeza de 10 vagas para programador JEE minimo 8 vão pedir do candidato Struts como requisito.
Uma vez com o JBoss configurado, clique em File ==> Project
Localize o diretório Jboss Tools Web
E agora dentro do diretório Struts escolha Struts Project
Clique em next
Dê um nome ao seu projeto e clique em next
Agora escolha o servidor. Nesse caso vamos usar usar TomCat 6
clique em Next
Clique em finish
A estrutura criada deve ser a semelhante a imagem a seguir.
Agora vamos criar uma classe Java com Struts que vai imprimir apenas uma mensagem no browser confirmando a execução do Struts. Portanto crie um package br.com.camilo.struts
Agora crie uma nova classe no package criado no passo anterior, com o nome de TesteStruts tendo como SuperClass a classe Action do Struts. Veja como deve ficar:
Agora atualize sua classe com o código abaixo
package br.com.camilo.struts;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class TesteStruts extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception{
/* esse metodo retorna uma mensagem para o struts-config.xml
* ao chegar no arquivo struts-config.xml e encontrar o nome done
* a pagina eh encaminhada para um arquivo .jsp
*/
return mapping.findForward("done");}}
Mas por que fazer o forward via arquivo .xml do Struts se posso fazer direto do arquivo .java colocando o xx.jsp ??
A resposta é bem simples se o nome do arquivo mudar, e vc tem 10 classes que faz esse forward para aquele arquivo o que fazer? Atualizar manualmente arquivo por arquivo e se vc esquecer de 1 ou 2 ou mais. Se for 100 arquivos ? Então percebeu o problema? Com o .xml vc somente vai precisar alterar em um local o novo nome do arquivo. Claro que vc pode cair na mesma situação se inventar de alterar o nome de retorno para aquele tipo de redirecionamento, mas ai é outra situação.
crie agora um arquivo .jsp chamado de teste.jsp (clique com o botão direito no projeto ==> New File ==> JSP )
Dentro da tag <body> digite a mensagem que deseja visualizar para testar a funcionalidade do Struts.
Agora abra o arquivo struts-config.xml no modo Source.(veja no rodapé do eclipse esta opção)
Precisamos configurar agora o nosso arquivo .xml do Struts para fazer o redirecionamento é bem simples. Deixe conforme a seguir. Um
Erro comum a ser cometido é o esquecimento de colocar / no path e o nome class em type.
Esse .do vem la da configurado do arquivo web.xml, abra o arquivo e veja pq nesse caso devemos ter o .do. Não existe nenhum arquivo físico com esta extensão é apenas um nome lógico utilizado e uma recomendação.
Antes de testar aplicação precisamos reiniciar o TomCat então clique no botão do meio.
Se não encontra-lo, veja em que perspectiva vc está usando. Deveria ser Java EE
Agora abra o webbrowser dentro do próprio eclipse
E digite o endereço abaixo, caso seguiu o mesmo nome usado nesse post
http://localhost:8080/BlogStruts/testando.do
O resultado deve ser o seguinte:
Bom vou ficando por aqui e espero que tenham gostado dessa pequena introdução com Struts. Foi na verdade mais uma motivação para quem colocou o framework na lista de estudos. Abraco a todos e até o próximo post.
Criando Projeto Struts no Eclipse usando Jboss tools
Olá Pessoal,
Nesse post veremos como criar um projeto Struts no Eclipse, veja como é bem simples ter um Struts Project usando o Jboss Tools. Se não tem o Jboss tools configurado no eclipse veja o “post relacionado”. O objetivo deste post é para quem está querendo dar os primeiros passos com Struts, porem nao sabe por onde começar.
Lets go…
Não irei abordar alguns conceitos tais como: vantagens, quando usar?, por que usar?. Na verdade isso daria um novo post. Para quem tiver interesse em saber mais sobre Struts podem dar uma olhada no link a seguir e também nas vagas de emprego para Java, tenho 99% de certeza de 10 vagas para programador JEE minimo 8 vão pedir do candidato Struts como requisito.
Uma vez com o JBoss configurado, clique em File ==> Project
Localize o diretório Jboss Tools Web
E agora dentro do diretório Struts escolha Struts Project
<struts1>
Clique em next
Dê um nome ao seu projeto e clique em next
<struts2>
Agora escolha o servidor. Nesse caso vamos usar usar TomCat 6
<struts3>
clique em Next
<struts4>
Clique em finish
A estrutura criada deve ser a semelhante a imagem a seguir.
<struts5>
Agora vamos criar uma classe Java com Struts que vai imprimir apenas uma mensagem no browser confirmando a execução do Struts. Portanto crie um package br.com.camilo.struts
Agora crie uma nova classe no package criado no passo anterior, com o nome de TesteStruts tendo como SuperClass a classe Action do Struts. Veja como deve ficar:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception{
/* esse metodo retorna uma mensagem para o struts-config.xml
* ao chegar no arquivo struts-config.xml e encontrar o nome done
* a pagina eh encaminhada para um arquivo .jsp
*/
return mapping.findForward(“done”);
}
}
Mas por que fazer o forward via arquivo .xml do Struts se posso fazer direto do arquivo .java colocando o xx.jsp ??
A resposta é bem simples se o nome do arquivo mudar, e vc tem 10 classes que faz esse forward para aquele arquivo o que fazer? Atualizar manualmente arquivo por arquivo e se vc esquecer de 1 ou 2 ou mais. Se for 100 arquivos ? Então percebeu o problema? Com o .xml vc somente vai precisar alterar em um local o novo nome do arquivo. Claro que vc pode cair na mesma situação se inventar de alterar o nome de retorno para aquele tipo de redirecionamento, mas ai é outra situação.
crie agora um arquivo .jsp chamado de teste.jsp (clique com o botão direito no projeto ==> New File ==> JSP )
Dentro da tag <body> digite a mensagem que deseja visualizar para testar a funcionalidade do Struts.
Executando minha pagina com Struts
Agora abra o arquivo struts-config.xml no modo Source.(veja no rodapé do eclipse esta opção)
Precisamos configurar agora o nosso arquivo .xml do Struts para fazer o redirecionamento é bem simples. Deixe conforme abaixo:
<code>
Erro comum a ser cometido é o esquecimento de colocar / no path e o nome class em type.
Esse .do vem la da configurado do arquivo web.xml, abra o arquivo e veja pq nesse caso devemos ter o .do. Não existe nenhum arquivo físico com esta extensão é apenas um nome lógico utilizado e uma recomendação.
Antes de testar aplicação precisamos reiniciar o TomCat então clique no botão do meio.
<struts7>
Se não encontra-lo, veja em que perspectiva vc está usando. Deveria ser Java EE
Agora abra o webbrowser dentro do próprio eclipse
<struts8>
E digite o endereço abaixo, caso seguiu o mesmo nome usado nesse post
http://localhost:8080/BlogStruts/testando.do
O resultado deve ser o seguinte:
<struts9>
Bom vou ficando por aqui e espero que tenham gostado dessa pequena introdução com Struts. Foi na verdade mais uma motivação para quem colocou o framework na lista de estudos. Abraco a todos e até o próximo post.