com Spring Security Felipe Nisrallah Saab 1 Segurana em Projeto s WEB com Spring Security Sumrio ..............................................................................................................................................................1 Segurana em Projetos WEB ...............................................................................................................1 com Spring Security.............................................................................................................................1 INTRODU!O...................................................................................................................................." #r$ui%os para &o'n(oa&.......................................................................................................................) *RI#NDO O PRO+ETO......................................................................................................................) *rian&o o DataBase e a Ta,e(a &e usu-rios.....................................................................................) Projeto no Ec(ipse.STS..................................................................................................................../ #&icionan&o o Spring na ap(ica0o.................................................................................................1 #&icionan&o segurana na ap(ica0o...............................................................................................2 #&icionan&o Usu-rios......................................................................................................................3 #utentica0o....................................................................................................................................3 4u&ar o pre5i6o &o tipo &e autori7a0o.........................................................................................18 #cesso Nega&o..............................................................................................................................18 9ogout............................................................................................................................................1" 8 Segurana em Projeto s WEB com Spring Security INTRODUO O Spring Security antes era conhecido como Acegi Security pois era um projeto paralelo ao Spring Framework e aos poucos foi integrado a ele. Quando eu digo integrado eu quero dizer que ele (Acegi Securit! continuou sendo desen"ol"ido #aseado no Spring$ ou seja$ ele funciona perfeitamente so#re o container do Spring. %& algum tempo o nome do projeto foi alterado para Spring Securit pois ele aca#ou entrando para a fam'lia do Spring. (esmo com a integra)*o$ quando "oc+ #ai,a o Spring Framework o Spring Security n*o "en incluso. -recisamos #ai,&.lo separadamente. / Spring Securit utiliza uma #i#lioteca e,terna para logging das suas fun)0es e essa #i#lioteca tam#1m n*o "em no download do projeto$ portanto temos que #ai,ar tam#1m o Apache 2ommons 3ogging. Apenas mais um detalhe4 se "oc+ acompanhou os posts anteriores so#re o Spring Framework "oc+ notou que a "ers*o do framework era a 5.6 (que "em nati"amente com o 7et8eans 9.:!$ por1m neste post eu j& irei utilizar a mais no"a "ers*o4 ;.< pois o Spring Securit ;.< ("ers*o melhor e mais f&cil de usar do que a anterior! s= roda em cima do Spring Framework ;.<. 7esse post$ "ou trocar a >?@ tam#1m$ ao in"1s de utilizar o 7et8eans eu irei utilizar o SpringSource Aool Suite (@clipse que o pessoal da SpringSource deu uma tur#inada para facilitar a "ida de quem usa o Spring!. " Segurana em Projeto s WEB com Spring Security Arquivos para download Seguem os (in:s para os &o'n(oa&s necess-rios; Spring Framework ;.< Spring Securit ;.< Apache 2ommons 3ogging B.B.B SpringSource Aool Suite (caso queira conhecer a ferramenta! Aam#1m ser& necess&rio fazer o download do dri"er C?82 para a cone,*o com o #anco de dados que "oc+ for utilizar. @u irei utilizar o (SQ3$ caso "oc+ tam#1m use ele pode pegar o dri"er aui! "#$AN%O O P#O&E'O 7*o 1 do escopo desse artigo ensinar o uso do (SQ3$ portanto$ "oc+ de"er& ter conhecimento do uso do mesmo. @m nossa aplica)*o$ teremos dois tipos de usu&rios na aplica)*o que s*o Funcion&rios e Derentes. /s funcion&rios tem acesso apenas E &rea restrita a funcion&rios e os gerentes tem acesso tanto E &rea de funcion&rios quanto E &rea restrita aos gerentes. A autentica)*o ser& #aseada nos dados contidos em uma ta#ela no #anco de dados$ ent*o para o usu&rio possuir acesso ele de"e estar cadastrado no #anco de dados. Criando o DataBase e a Tabela de usurios CREATE DATABASE spring_security CREATE TABLE users ( username varchar(15) collate utf8_unicode_ci NOT NULL, password varchar(40) collate utf8_unicode_ci DEFAULT NULL, authority varchar(30) collate utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (username) ) 2om o #anco de dados pronto n=s j& podemos por a m*o na massaF ) Segurana em Projeto s WEB com Spring Security Projeto no Eclipse/STS 2riei um no"o projeto (?namic Ge# -roject! no SAS (SpringSource Aool Suite! chamado 2ontroleAcesso e a primeira coisa que fiz foi incluir as depend+ncias no classpath$ ou seja$ todos os .jar encontrados na pasta Hdist dos releases do Spring Framework e do Spring Securit e tam#1m o .jar do Apache 2ommons 3ogging e o .jar o dri"er C?82 do (SQ3. / projeto tem uma estrutura #em #&sica onde n=s podemos "er que as p&ginas que est*o na raiz da aplica)*o s*o as p&ginas de login$ inde, e uma respons&"el por mostrar uma mensagem de acesso negado caso o usu&rio tente acessar uma p&gina que n*o pode. ?epois e,istem mais duas pastas (funcionario e gerente! representando as partes da aplica)*o que somente usu&rios autenticados podem acessar. 7estas pastas eu coloquei apenas um inde, para confirmar que ti"emos acesso ou n*o a p&gina. Iamos come)ar a "er as p&ginas ent*o4 index.jsp (raz): <%@ page language="java" contentType="text/html; charset=ISO-8859- 1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Home Page</title> </head> / Segurana em Projeto s WEB com Spring Security <body> <h1>Pgina de Boas Vindas</h1> <a href="./funcionario">rea de Funcionrios</a> <br/> <a href="./gerente">rea de Gerentes</a> </body> </html> A p&gina inicial da aplica)*o apenas d& as #oas "indas ao usu&rio e mostra os poss'"eis caminhos para ele na &rea de funcion&rios ou de gerentes. funcionario/index.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859- 1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>rea do Funcionrio</title> </head> <body> <h1>Bem Vindo a rea do Funcionrio</h1> <a href="../index.jsp">Retornar para a Pgina Inicial</a> </body> </html> gerente/index.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859- 1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>rea do Gerente</title> </head> <body> <h1>Bem Vindo a rea do Gerente</h1> <a href="../index.jsp">Retornar para a Pgina Inicial</a> </body> </html> -ronto$ esta 1 a estrutura #&sica da aplica)*o. 7o momento$ < Segurana em Projeto s WEB com Spring Security podemos na"egar li"remente pelas &reas que de"em ser restritas (funcion&rios e gerentes!$ pois a seguran)a ainda n*o foi configurada. Adicionando o Spring na aplicao / pr=,imo passo ser& configurar o Spring para funcionar nessa nossa aplica)*o. 2omo as #i#liotecas j& est*o no classpath ent*o "amos criar o arqui"o de configura)*o do Spring4 dentro da pasta WEB($NF crie um ,ml chamado Japplication"onte)tJ. 2aso esteja usando o SAS #asta clicar com o #ot*o direito na pasta WEB($NF$ ir em New e depois em Other. I& na pasta Spring e selecione Spring Bean Configuration File$ na pr=,ima janela digite o nome (application"onte)t! e na pr=,ima janela "oc+ pode escolher os namespaces que quer usar no arqui"o. Selecine beans e sec. Quando selecionar o sec "oc+ ainda de"e especificar o KS? do Spring Framework ;.<. Fazendo isso a >?@ j& "ai criar a estrutura #&sica do arqui"o de configura)*o com todos os namespaces. / application"onte)t!)ml de"e ficar parecido com este (j& "ou adiantar um detalhe e declarar o dataSource respons&"el por se comunicar com o #anco de dados onde est& a ta#ela com os usu&rios e suas autentica)0es!4 *+)ml "ersionLMB.<M encodingLMNAF.:M+, *beans ,mlnsLMhttp4HHwww.springframework.orgHschemaH#eansM ,mlns4,siLMhttp4HHwww.w;.orgH5<<BHK(3Schema.instanceM ,mlns4secLMhttp4HHwww.springframework.orgHschemaHsecuritM ,si4schema3ocationLMhttp4HHwww.springframework.orgHschemaH#eans http4HHwww.springframework.orgHschemaH#eansHspring.#eans.,sd http4HHwww.springframework.orgHschemaHsecurit http4HHwww.springframework.orgHschemaHsecuritHspring.securit.;.<.,sdM, <!-- data source --> *bean idLMdataSourceM classLMorg.springframework.jd#c.datasource.?ri"er(anager?ataSourceM, *property nameLMdri"er2lass7ameM "alueLMcom.msql.jd#c.?ri"erM -, *property nameLMurlM "alueLMjd#c4msql4HHlocalhostHspringOsecuritM -, *property nameLMusernameM "alueLMrootM -, *property nameLMpasswordM "alueLMM -, *-bean, *-beans, -ara concluir esta etapa #asta fazer uma pequena modifica)*o no 1 Segurana em Projeto s WEB com Spring Security web!)ml para adicionar um listener que o Spring tem para facilitar nossa "ida. Sempre que a aplica)*o "ai come)ar a funcionar esse listener procura pelo arqui"o application"onte)t!)ml e carrega o Spring e os #eans e configura)0es definidos nesse arqui"o. Aem como configurar o listener para rece#er uma lista com o nome de "&rios arqui"os de configura)*o (caso "oc+ goste de separar as configura)0es em arqui"os separados! e ent*o ele carrega todos$ por1m esse 1 um assunto para outro post (ou uma r&pida #usca no google!. 8asta adicionar a seguinte tag no we#.,ml4 *listener, *listener( class,org.springframework.we#.conte,t.2onte,t3oader3istener*-listener(class, *-listener, 2aso "oc+ e,ecute a aplica)*o agora e fique atento Es mensagens de 3/D "oc+ ir& "er o Spring carregando e o dataSource sendo configurado$ ou seja$ tudo indo #em at1 aquiF Ali&s$ "er& tam#1m que "oc+ consegue facilmente acessar as &reas que de"eriam ser restritas. Audo certo at1 aqui. Adicionando segurana na aplicao Iamos come)ar a fazer algumas modifica)0es para podermos adicionar a seguran)a na nossa aplica)*o. -rimeiro de tudo "amos adicionar um no"o filtro no nosso web!)ml. @sse filtro ser& respons&"el por interceptar todas as requisi)0es E aplicac*o$ "erificar se o usu&rio possui acesso e li#erar a requisi)*o normalmente ou ent*o mostrar um erro. Segue o K(3 necess&rio para a declara)*o e configura)*o do filtro4 *.ilter, *.ilter(name,springSecuritFilter2hain*-.ilter(name, *.ilter( class,org.springframework.we#.filter.?elegatingFilter-ro,*-.ilter(class, *-.ilter, *.ilter(mapping, *.ilter(name,springSecuritFilter2hain*-.ilter(name, *url(pattern,HP*-url(pattern, *-.ilter(mapping, 2 Segurana em Projeto s WEB com Spring Security A partir de agora todas as requisi)0es ser*o interceptadas pelo Spring$ s= falta dei,ar #em claro para o Spring Securit quem pode fazer o que na aplica)*o. Antes de continuar com o processo de autentica)*o de usu&rios n=s precisamos ter o usu&rios concordaQ Adicionando Usurios
Iamos adicionar dois usu&rios para testes de nossa aplica)*o4 um gerente e um funcion&rio comum. >7S@RA >7A/ users (username$password$authorit! IA3N@S(SfuncS$SfuncS$SR/3@OFN72S!T >7S@RA >7A/ users(username$password$authorit! IA3N@S(SgerS$SgerS$SR/3@OD@RS!T Agora j& temos o usu&rio .unc e o usu&rio ger para poder testar na nossa aplica)*o. Ieja que o atri#uto authority foi preenchido com #O/E0F1N" e #O/E02E#. >sso ocorre porque o Spring Securit sempre #usca um prefi,o no tipo de autoriza)*o de cada usu&rio e o padr*o 1 este (JR/3@OU!. 3ogo mais mostrarei como trocar para um prefi,o a sua escolha como JFN72A/OU$ JANA%OU ou o que "oc+ quiser. Autenticao Aoda a autentica)*o ser& feita com a declara)*o de apenas dois #eans no application"onte)t!)ml. Iamos ao primeiro4 <sec:http auto-config="true"> <sec:form-login login-page="/login.jsp" authentication- failure-url="/login.jsp?erro=invalido" /> <sec:intercept-url pattern="/funcionario/**" access="ROLE_FUNC" /> <sec:intercept-url pattern="/gerente/**" access="ROLE_FUNC,ROLE_GER" /> <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> </sec:http> 3 Segurana em Projeto s WEB com Spring Security / prefi,o das tags dos Spring Securit 1 JsecU pois foi o namespace declarado para ele na tag root 4 ,mlns4secLUVU A tag ser"e para definir os parWmetros #&sicos para o Spring Securit sa#er o que fazer com as requisi)0es. / atri#uto auto. config nos poupa de definir todas as tags necess&rias para o funciomento correto$ sendo assim$ s= precisamos nos focar no que realmente faz parte da nossa aplica)*o$ como o que eu coloquei4 formul&rio de login e NR3s que ser*o interceptadas. 2ada tag X intercept.url Y identifica uma NR3 ou um padr*o de NR3s e qual a permiss*o o usu&rio de"e ter para acessar tal (tais! NR3 (s!. A primeira tag diz que todas as NR3s que comecem com JHfuncionarioHU s= poder*o ser acessadas por usu&rios que ti"erem autoriza)*o R/3@OFN72 ou R/3@OD@R. C& a segunda restringe o acesso a todas NR3s que comecem com JHgerenteHU para usu&rios que esti"erem autorizados com R/3@OD@R. @ a Zltima tag define que qualquer outra NR3 que ainda n*o foi definida anteriormente pode ser acessada sem autentica)*o nenhuma. 7a tag X form.loginY foram definidos alguns atri#utos meio #&sicos4 login.page informando qual 1 a p&gina de login e authentication.failure.url informando qual 1 a p&gina que ser& e,i#ida caso o login falhe (neste caso eu coloquei a mesma p&gina de login e apenas en"iei um parWmetro "ia D@A para podermos sa#er quando ocorre o erro!. Segue a p&gina de login e como de"e ser o formul&rio4 <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Autenticao</title> </head> <body> <c:if test="${param.erro == 'invalido'}"> Usurio e/ou senha invlidos!<br/><br/> 1= Segurana em Projeto s WEB com Spring Security </c:if>
<form action="j_spring_security_check" method="post"> Usurio: <input type="text" name="j_username" /><br /> Senha: <input type="password" name="j_password"><br /> <input type="submit" value="Efetuar Login"> </form> <br /><br /> <a href="index.jsp">Retornar para a Pgina Inicial</a> </body> </html> 2aso a p&gina seja carregada com o parWmetro JerroU contendo o "alor Jin"alidoU ent*o um erro ser& mostrado (fiz usando CSA3!. @ o formul&rio de login de"e ser en"iado para a NR3 JjOspringOsecuritOcheckU passando como parWmetros o nome de usu&rio (jOusername! e a senha (jOpassword!. @sses nomes s*o padr0es do Spring Framework e #em f&ceis de serem seguidos. / processo de login 1 simples assim e encerra as e,plica)0es so#re o primeiro #ean respons&"el pela seguran)a de nossa aplica)*o. Iamos ao pr=,imo #ean4 <sec:authentication-manager> <sec:authentication-provider> <sec: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, authority FROM users WHERE username=?" /> </sec:authentication-provider> </sec:authentication-manager> ?entro do X authentication.manager Y 1 onde especificamos onde o Spring Securit de"e #uscar os dados para "erificar se um usu&rio est& autenticado ou n*o. 2omo j& tinhamos pre"isto desde o come)o do post que ir'amos fazer a autentica)*o atra"1s do #anco de dados$ utilizamos a tag X jd#c.user.ser"ice.data.source Y passando o dataSource que conecta no #anco que cont1m nossos usu&rios. Quando o Spring Securit tenta autenticar um usu&rio com dados "indos de um #anco de dados ele possui um padr*o4 para cada usu&rio de"em ser retornados ; campos4 username$ password e ena#le$ sendo eles usu&rio$ senha e o Zltimo dizendo se o usu&rio est& ha#ilitado ou n*o. 11 Segurana em Projeto s WEB com Spring Security -ara n*o ficarmos presos no padr*o de ta#elas que o Spring Securit sugere para usu&rios$ n=s podemos escre"er quais quers ele ir& utilizar para recuperar os dados que ele precisa. / atri#uto users.#.username.quer de"e trazer os dados do usu&rio (username$ password e ena#led! selecionado pelo nome de usu&rio e o atri#uto authorities.#.username.quer de"e trazer o nome de usu&rio e o tipo de autentica)*o (username$ authorit! tam#1m selecionado pelo nome de usu&rio. 2om essa fle,i#ilidade de configura)*o 1 poss'"el utilizar qualquer estrutura de ta#elas respons&"el por armazenar os usu&rios. -rontoF Agora nossa aplica)*o we# j& possui um mecanismo de seguran)a para restringir o acesso apenas a usu&rios autenticadosF @,ecutando a aplica)*o agora "oc+ "er& que s= consegue acessar a &rea de funcion&rios autenticando.se como um funcion&rio ou gerente$ e,atamente como ha"'amos configurado. Mudar o prefixo do tipo de autorizao -ara mudar o prefi,o padr*o (R/3@O! podemos setar o atri#uto role. prefi, da tag X jd#c.user.ser"ice.data.source Y. <sec:authentication-manager> <sec:authentication-provider> <sec:jdbc-user-service data-source-ref="dataSource" role- prefix="TIPO_" users-by-username-query="SELECT username, password, 'true' as enable FROM users WHERE username=?" authorities-by-username-query="SELECT username, authority FROM users WHERE username=?" /> </sec:authentication-provider> </sec:authentication-manager> 2om essa configura)*o os prefi,os de"em ser JA>-/OU. @, de tipos de autoriza)*o4 A>-/OD@R@7A@ e A>-/OFN72>/7AR>/. Acesso Negado 2aso o usu&rio logado como funcion&rio queira acessar a se)*o restrita a gerentes ele ir& rece#er uma p&gina de erro #em 18 Segurana em Projeto s WEB com Spring Security estranha (que o ser"idor de aplicati"os gera!. -ara mostrar uma p&gina mais amig&"el a"isando que o usu&rio n*o tem acesso a uma certa &rea #asta preencher o atri#uto access.denied.page da tag X http Y. <sec:http auto-config="true" access-denied-page="/negado.jsp"> <sec:form-login login-page="/login.jsp" authentication- failure-url="/login.jsp?erro=invalido" /> <sec:intercept-url pattern="/funcionario/**" access="ROLE_FUNC,ROLE_GER" /> <sec:intercept-url pattern="/gerente/**" access="ROLE_GER" /> <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> </sec:http> negado.jsp: <sec:authentication-manager> <sec:authentication-provider> <sec:password-encoder hash="md5"/> <sec:jdbc-user-service data-source-ref="dataSource" role- prefix="TIPO_" users-by-username-query="SELECT username, password, 'true' as enable FROM users WHERE username=?" authorities-by-username-query="SELECT username, authority FROM users WHERE username=?" /> </sec:authentication-provider> </sec:authentication-manager> 7este caso o algoritmo usado 1 o (?6$ poderia ser o (?[$ S%A$ entre outros. -ara inserir o usu&rio com uma senha criptografada com (?6 no (SQ3 fica assim4 >7S@RA >7A/ users (username$password$authorit! IA3N@S(SfuncS$(?6(SfuncS!$SR/3@OFN72S!T Logout -ara o usu&rio efetuar logout no sistema #asta acessar a NR3 JjOspringOsecuritOlogoutU na raiz da aplica)*o. @,4 para colocar um link JSairU na p&gina HfuncionarioHinde,.jsp de"emos colocar assim4 1" Segurana em Projeto s WEB com Spring Security Xa hrefLM..HjOspringOsecuritOlogoutMYSairXHaY 2omo a url de"e ser acessada na raiz da aplica)*o we#4 HAplicacaoHjOspringOsecuritOlogout e n*o HAplicacaoHfuncionarioHjOspringOsecuritOlogout. @ chegamos ao final de mais um post. / projeto do SAS est& dispon'"el para download aqui. 1)