Customizar form de login Spring Security [Resolvido]

20 respostas
A

Olá pessoal!
a algumas semanas estou “brigando feio” com o Spring Security na versão 3.0.5.
O login básico funciona sem problemas… mas eu preciso de algo além disso!
Por exemplo, eu tenho o seguinte form que funciona:

<form action="j_spring_security_check" method="post" >
                <h:panelGrid columns="2">
                    <h:outputLabel value="Login" for="j_username" />
                    <h:inputText id="j_username" required="true" requiredMessage="Informe o login" />
                    <h:outputLabel value="Senha" for="j_password" />
                    <h:inputSecret id="j_password" required="true" requiredMessage="Informe a senha" />
                </h:panelGrid>
                <h:commandButton type="submit" value="Login" />
            </form>

Mas eu preciso de algo tipo isso:

<form action="j_spring_security_check" method="post" >
                <h:panelGrid columns="2">
                    <h:outputLabel value="Login" for="j_username" />
                    <h:inputText id="j_username" required="true" requiredMessage="Informe o login" />
                    <h:outputLabel value="Senha" for="j_password" />
                    <h:inputSecret id="j_password" required="true" requiredMessage="Informe a senha" />
                    <h:outputLabel value="Filial" for="j_filial" />
                    <h:selectOneMenu id="j_filial" style="width: 200px" value="#{loginBean.codigoFilial}">
                        <f:selectItems value="#{filialBean.filiais}" />
                    </h:selectOneMenu>
                </h:panelGrid>
                <h:commandButton type="submit" value="Login" />
            </form>

Ou seja, o usuario precisa selecionar a qual filial o mesmo pertence, o problema está sendo apenas mandar esse codigo da filial para o bean.
Para a validação do j_spring_security_check: eu tenho um LoginBean que implementa o AuthenticationManager do Spring …
nele eu tenho um:

com get e set …
mas o mesmo retorna null!
Imagino que eu tenha que mapear por exemplo um, j_filial ligado a esse codigoFilial no spring-security.xml
mas não sei onde coloco esse atributo no xml!

Segue também o codigo do spring-security.xml

<security:http auto-config="false" use-expressions="true" access-denied-page="/negado.jsf" entry-point-ref="authenticationEntryPoint" >
        <security:intercept-url pattern="/adm/**" access="hasRole('ROLE_ADM')"/>
        <security:intercept-url pattern="/user/**" access="hasRole('ROLE_USER')"/>

        <security:logout invalidate-session="true" logout-success-url="/login.jsf" logout-url="/logout"/>

        <security:custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>
    </security:http>

    <bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" p:authenticationManager-ref="customAuthenticationManager" p:authenticationFailureHandler-ref="customAuthenticationFailureHandler" p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler" />

    <bean id="customAuthenticationManager" class="br.com.amazoniasistemas.login.LoginBean" />
    <bean id="customAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" p:defaultFailureUrl="/erro.jsf" />
    <bean id="customAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler" p:defaultTargetUrl="/index.jsf" />
    <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" p:loginFormUrl="/login.jsf"/>
    <security:authentication-manager/>

Grata pela atenção
:roll:

20 Respostas

A

Alguém!?
O que estão usando para autenticação e autorização no JEE 6?

A

Tá vou mudar minha pergunta…
Tem alguém aí que entende de Spring Security 3.0?
Preciso saber que filtro eu posso implementar ou extender que esteja entre o form de login e o AuthenticationManager…

Assim:
submit no form --> passa pelo filtro que eu quero --> e vai para o AuthenticationManager.

J

Gostaria de saber se vc sabe pegar o usuário logado do spring e mostrar ele na tela ! ?

J
<?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.0.xsd"
             >

   <!--
    <http auto-config="true">
        <form-login login-page="/" authentication-failure-url="/?error=invalido" default-target-url="/admin"/>
        <intercept-url  pattern="/admin/**" access="ROLE_ADMIN" />
        <intercept-url  pattern="/usuario/**" access="ROLE_USER" />
    </http>
    -->
    <http auto-config='true' access-denied-page="/WEB-INF/jsp/index/negado.jsp">
        <form-login login-page="/" authentication-failure-url="/?error=invalido" default-target-url="/menu" />
          <!--<intercept-url pattern="/index/index.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>-->

    	 <intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
         <intercept-url pattern="/usuario/**" access="ROLE_USER"/>
         <intercept-url pattern="/gerente/**" access="ROLE_GERENTE"/>
         <intercept-url pattern="/index/**" access="ROLE_GERENTE,ROLE_USER,ROLE_ADMIN"/>
         
         <!--<intercept-url pattern="/usuario/index.jsp" access="ROLE_ADMIN" />-->
         <session-management> 
         <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
         </session-management>
        <!--<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />-->
    	<!--<concurrent-session-control max-sessions="1"/>-->
    	<logout logout-url="/logout" logout-success-url="/"/>
  	</http>
    <!--
        <authentication-manager>
                <authentication-provider>
                <password-encoder hash="md5" />
                <jdbc-user-service data-source-ref="dataSource"
                    users-by-username-query="SELECT email as username,
                    senha as password,
                    'true' as enable
                    FROM nutec.usuario WHERE email = ?"
                    authorities-by-username-query="SELECT u.email as username,
                    r.nome as nutec.authority
                    FROM nutec.usuario u,
                    regra r WHERE u.regra_id = r.id AND email = ?"/>
                </authentication-provider>
        </authentication-manager>
        -->
         <!--selec no banco users authorities-->
    <authentication-manager>
        <authentication-provider>
            <!--<password-encoder hash="md5" />-->
            <jdbc-user-service data-source-ref="dataSource"

                 users-by-username-query="SELECT users.username,users.password,'true' AS enabled FROM financeiro2.users WHERE users.username=?"
                 authorities-by-username-query="SELECT authorities.username,authorities.autority FROM financeiro2.authorities WHERE authorities.username=?"/>

        </authentication-provider>
    </authentication-manager>
    <!--selec no banco users authorities   FIM -->
    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <beans:property name="url" value="jdbc:postgresql://localhost:5432/nutec" />
        <beans:property name="driverClassName" value="org.postgresql.Driver" />
        <beans:property name="username" value="root" />
        <beans:property name="password" value="debian23" />
    </beans:bean>
</beans:beans>
A

Olá, então estou começando agora com Spring, então não sei muita coisa,
o que eu pretendo fazer é, um bean para fazer a autenticação e quando ele autenticar setar um usuario com escopo de sessão!

J

Ta usando JSF 1 ou 2 ? quer ajuda ?

tenho um demo : http://www.4shared.com/file/bHw6AsbH/clientestar.html

A

Obrigada :slight_smile:
então estou usando o JSF 2.0, esse problema eu consegui resolver estendendo a classe: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
e implementei o método public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) como eu precisava…
meu problema é outro agora, estou tendo um nullpointer quando tento fazer isso:

FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, failed.toString(), null));
dentro dessa mesma classe que eu faço a autenticação…
o nullpointer ocorre no context.addMessage(…)
se vc souber como posso usar o FacesContext nessa classe, já me ajudaria pra caramba :smiley:

J

baixa meu demo e da uma olhada !

A

estou baixando, tem algo referente ao que falei sobre o FacesContext?

A

juniorsatanas, qual é a parte que eu tenho que olhar no seu projeto? dei uma olhada por cima mas não encontrei o que eu estava precisando…

J

nesse projeto tem :

# FacesContext context = FacesContext.getCurrentInstance();

context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, failed.toString(), null));

implementado !

O que você ta querendo fazer no seu Projeto e o que ta dando erro ?

A

seria isso, mas não sei se é pq minha classe extend um Filter ou sei lá por que, o FacesContext dá nullPointer … então eu preciso de um exemplo dele dentro de um Filter, tem algo nesse projeto?

J

Não tenho nesse não !

Ta usando Rick ou Primefaces ?

Manda para mim como ta feito isso : [email removido] , vou da uma olhada e te falo alguma coisa...

jr

A

Uso o primeFaces, mas o problema nem é ele, é a minha logica… pq eu preciso retornar uma mensagem para pessoa <h:message /> ou <p:grolw /> do primeFaces… Se um funciona, o outro tambem!

J

da uma olhada : http://forums.oracle.com/forums/thread.jspa?threadID=1038827

A

Sei que está marcado como resolvido, e faz tempo… mas não encontrei solução.

Então, como todo bom brasileiro, resolvi dar o meu jeito nesse problema.

O sistema de login é o mesmo para todos os usuários (não importa a filial, o usuário preenche apenas usuário e senha).
Na tela seguinte, é apresentado ao usuário uma lista (na verdade são desenhos quadrados bonitos (ícones)) de todas as filiais que ele pode acessar.
Se o usuário tem apenas uma filial já vai direto para a página principal
Existe um link para ele voltar para essa página caso precise alterar a filial da sessão corrente.

Essa é apenas uma outra abordagem do seu problema. E eu acho melhor afinal ao invés do usuário ter que ficar digitando números (e decorando eles)
O usuário tem uma interface que faz isso pra ele (e apenas quando necessário).

A

Olá pessoal! Desculpa a demora, acabei não postando a solução pois saí da empresa em que precisava disso a um tempo, e acabei não ficando com nenhum código implementado sobre isso :S

J

andii, por favor, como você fez para incluir este campo na autenticação?

Não to conseguindo fazer isso e meu problema é bem parecido.

Preciso incluir na autenticação mais campos do que somente usuário e senha.

Desde já agradeço a ajuda.

J

Oi andii, será que você poderia me enviar um exemplo de como você incluiu este campo a mais na autenticação do Spring?

Não to conseguindo fazer.

A

Olá pessoal!

Sei que esse problema meu foi a anos, mas acredito que ainda tenha gente que esteja com o mesmo problema.
Então arrumei um tempinho e resolvi escrever no blog essa solução:
http://javasemcafe.blogspot.com.br/2013/07/login-customizado-com-spring-security.html
Espero que ajude!

Criado 5 de janeiro de 2011
Ultima resposta 9 de jul. de 2013
Respostas 20
Participantes 4