Adicionar Spring Security 3.2.0.M1 ao Projeto

Prezados,

Tenho um pequeno projeto em desenvolvimento, utilizando as seguintes tecnologias: Netbeans 7.3.1, JPA 2, JSF 2.1, PrimeFaces, Mysql, GlassFish 3.1.2.2, utilizando Datasouce JNDI para conexão com o banco de dados.
Para acesso ao sistema, é pesquisado no banco de dados, se existe o login e senha digitados.
Estou precisando adicionar uma camada de segurança nesta aplicação.
Pesquisei sobre JAAS e Spring Security. Para atender os requisitos atuais, e já planejamento os requisitos futuros, a medida que o projeto for crescendo, optei por utilizar o Spring.
Sou leigo no assunto. Em minhas pesquisas, encontrei muita informação e exemplos, para configurar o Spring com Hibernate. Mas acredito que o meu caso seja diferente, pois utilizo conexão JNDI Datasource do Glassfish (me corrijam se estiver errado).

Sei que o Spring não é algo fácil de instalar e configurar, mas gostaria de ajuda para implantação basica.
Estou bem perdido. Alguém poderia me passar um tutorial, para que eu inicie e depois vá postando as duvidas aqui ?
Obrigado!

Olá,

No site do spring security há uma sugestão de caminhos para os iniciantes, dê uma olhada:

http://static.springsource.org/spring-security/site/start-here.html

[ ]'s

[quote=Ev3rton]Olá,

No site do spring security há uma sugestão de caminhos para os iniciantes, dê uma olhada:

http://static.springsource.org/spring-security/site/start-here.html

[ ]'s[/quote]

Ola Everton
Obrigado pela ajuda. Visitei o site que vc indicou… Mas me de bem com este tutorial:
http://javasemcafe.blogspot.com.br/2011/05/java-ee-6-seguranca-com-spring-security.html
Bem simples e pratico. A ideia de criar inicialmente um tutorial com um simples projeto sem banco de dados, foi excelente. Parabéns andii.brunetta !

Segui os passos no tutorial, para implementar o spring com BD.
Criei um projeto simples, para fins de aprendizado, apenas para testar dois tipos de acesso: admin e user
Na tabela, criei os seguintes campos: username, password, enable, authority.
Após varias tentativas, estou com dificuldades para faze-lo funcionar.

Após executar o projeto, quando eu digito um login/senha correto, surge a pagina de falha.xhtml "Login/Senha incorretos".
Depois do primeiro login, mesmo digitando login/senha, surgi o erro "HTTP Status 404", na seguinte URL:
http://localhost:8282/SpringSecurityBD/faces/j_spring_security_check

Acredito que seja alguma configuração nas navegações.
Alguém poderia me ajudar ?

Segue meus arquivos XML:

WEB.XML

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            1
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>

<!-- Spring security -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
 
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
<!-- Fim spring security -->

</web-app>

applicationContext

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
 
</beans:beans>

security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">

   <http auto-config="true" access-denied-page="/faces/negado.xhtml" use-expressions="true" >
        <intercept-url pattern="/faces/admin/**" access="ROLE_ADMIN" />
        <intercept-url pattern="/faces/comum/*" access="ROLE_USER" />
        
        <logout invalidate-session="true" logout-success-url="/faces/index.xhtml" logout-url="/logout" />
        
        <form-login
        login-page="/faces/login.xhtml"
        authentication-failure-url="/faces/falha.xhtml" 
  
        default-target-url="/faces/home.xhtml"
        username-parameter="username" 
        password-parameter="password" />
    </http>
    
    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <beans:property name="url" value="jdbc:mysql://localhost:3306/sistemabd" />
        <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <beans:property name="username" value="root" />
        <beans:property name="password" value="root" />
    </beans:bean>
     
    <authentication-manager>
        <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="SELECT username, password, 'enable' as enabled FROM users WHERE username=?"
                authorities-by-username-query="SELECT username, authority FROM users WHERE username=?"
            />
        </authentication-provider>
    </authentication-manager>
 
</beans:beans>

rootContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

	<!-- Root Context: defines shared resources visible to all other web components -->
	<import resource="applicationContext.xml"/>

</beans>

Olá,

Pode postar a sua página de login?

Para uma página de login você precisa ter um campo para o nome de usuário com o id definido como “j_username” e um para a senha com o id=“j_password”.

Você está usando JSF, então quando abrir a página no navegador, verifique se os campos de login estão mesmo com os ids que indiquei acima.

O erro 404 acontece porque sua página está direcionando para o endereço
http://localhost:8282/SpringSecurityBD/faces/j_spring_security_check quando deveria direcionar para http://localhost:8282/SpringSecurityBD/j_spring_security_check

[ ]'s

Everton,

No Netbeans, se não tiver o /faces/ no contexto, os componentes de formulário JSF e Primefaces não aparece. Talvez seja uma particularidade do Netbeans. Já usei o Eclipse, e sei que não tem este problema. Se alguém puder me fornecer uma dica, eu agradeço.
Efetuei diversos testes, para tentar direcionar para a URL http://localhost:8282/SpringSecurityBD/j_spring_security_check, mas sem sucesso.

A pagina login.xhtml, contem os campos que vc citou.
Segue o código:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>Login do Sistema</title>
        <link type="text/css" rel="stylesheet" />
    </h:head>
    <h:body>
        <p:dialog header="Login" visible="true" closable="false" draggable="false" resizable="false" width="420">
            <center>
                <h:outputText value="Usuário ou senha incorretos!" rendered="#{param.erro}" style="color: darkred"/>
            </center>
            <form action="j_spring_security_check" method="post">
                <h:panelGrid columns="2" cellpadding="5">
                    <h:outputLabel for="j_username" value="Username: *" /> 
                    <h:inputText id="j_username" required="true"/>
                    <h:outputLabel for="j_password" value="Password: * " />
                    <h:inputSecret id="j_password" required="true"/>
                    <h:commandButton value="Login"/>
                </h:panelGrid>
            </form>
        </p:dialog>
    </h:body>
</html>

Olá,

Para conseguir usar o jsf em páginas fora do diretório faces, no seu web.xml altere:

<servlet-mapping>  
    <servlet-name>Faces Servlet</servlet-name>  
    <url-pattern>/faces/*</url-pattern>  
</servlet-mapping> 

Para

<servlet-mapping>  
    <servlet-name>Faces Servlet</servlet-name>  
    <url-pattern>*.xhtml</url-pattern>  
</servlet-mapping> 

Assim você vai mapear todas as requisições para as páginas *.xhtml para o Faces Servlet.

E o seu botão tem que fazer uma requisição para a página /j_spring_security_check.

[ ]'s

No mapeamento do botão “efetuar login”, a action do form já está setada para: action=“j_spring_security_check"
Se eu deixar assim: action=”/j_spring_security_check", é direcionado para um erro de 404, pois a função do spring vai para esta URL:
http://localhost:8282/j_spring_security_check

Para resolver o problema da URL, alterei a action do form login para:

<form id=“login” method=“post” action="#{request.contextPath}/j_spring_security_check" >

Agora, todos os logins/senha que digito, sou redirecionado para a pagina de falha, indicando que tem algo errado no login e/ou senha.
Tem algo de errado no security.xml, que impede a consulta do login ?

Efetuei algumas alterações no security.xml, e tambem criei uma tabela chamada USER_ROLE, contendo as colunas USERNAME e ROLENAME.

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd"&gt;

   &lt;http auto-config="true" access-denied-page="/negado.xhtml" use-expressions="true" &gt;
        &lt;intercept-url pattern="/admin/**" access="ROLE_ADMIN" /&gt;
        &lt;intercept-url pattern="/comum/*" access="ROLE_USER" /&gt;
        
        &lt;logout invalidate-session="true" logout-success-url="/index.xhtml" logout-url="/logout" /&gt;
        
        &lt;form-login
        
        login-processing-url="/j_spring_security_check"
        always-use-default-target="true"
        default-target-url="/home.xhtml"
        authentication-failure-url="/falha.xhtml?erro=true" 
       /&gt;
        
        
    &lt;/http&gt;
    
    &lt;beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" &gt;
        &lt;beans:property name="url" value="jdbc:mysql://localhost:3306/sistemabd" /&gt;
        &lt;beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
        &lt;beans:property name="username" value="root" /&gt;
        &lt;beans:property name="password" value="root" /&gt;
    &lt;/beans:bean&gt;
     
    &lt;authentication-manager&gt;
        &lt;authentication-provider&gt;
            &lt;jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="SELECT username, password, enable FROM users WHERE username=?"
                authorities-by-username-query="SELECT username, rolename FROM user_role WHERE username=?"
            /&gt;
        &lt;/authentication-provider&gt;
    &lt;/authentication-manager&gt;
 
&lt;/beans:beans&gt;

Consegui fazer o login funcionar.
Alterei a consulta SQL, deixando assim:

users-by-username-query="SELECT username, password, 'true' AS enabled FROM users WHERE username = ?"
authorities-by-username-query="SELECT username, authority FROM users WHERE username=?"

O problema agora, é que as permissões não estão sendo carregadas (acredito eu), porque o ROLE_USER está conseguindo acessar pagina que tem somente permissão para ROLE_ADMIN.
Vou tentando aqui. Qualquer duvida, irei postar no fórum.

Da uma olhada no meu ai…

	<security:http use-expressions="true">
		<security:intercept-url pattern="/" access="permitAll"/>
		<security:intercept-url pattern="/views/user/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
		<security:intercept-url pattern="/views/admin/**" access="hasRole('ROLE_ADMIN')"/>
		<security:intercept-url pattern="/views/**" access="isAuthenticated()"/>
		<security:form-login login-page="/login.jsf" default-target-url="/views/main.jsf" authentication-failure-url="/login.jsf"/>
		<security:logout logout-success-url="/login.jsf" invalidate-session="true"/>
	</security:http>

Ola Alan

Obrigado pela colaboração.
Mas descobri porque não estava sendo verificado a permissão. Acontece que, na pagina home, que vem logo após o usuario entrar com login e senha, eu tinha alguns componentes para teste, commandbutton e link.
O commandbutton carregava a pagina solicitada, porem não muda a URL de navegação no browser. Através do link, a URL muda, portanto a segurança é verificada e o bloqueio acontece normalmente.
Como sou novato em JSF, vou pesquisar mais um pouco sobre o assunto.

Obrigado!