Customizar form de login Spring Security [Resolvido]

20 respostas
andii.brunetta

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

andii.brunetta

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

andii.brunetta

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.

juniorsatanas

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

juniorsatanas
<?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>
andii.brunetta

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!

juniorsatanas

Ta usando JSF 1 ou 2 ? quer ajuda ?

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

andii.brunetta

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:

juniorsatanas

baixa meu demo e da uma olhada !

andii.brunetta

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

andii.brunetta

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…

juniorsatanas

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 ?

andii.brunetta

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?

juniorsatanas

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

andii.brunetta

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!

juniorsatanas

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

aronrodrigues

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).

andii.brunetta

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.

andii.brunetta

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