1. java
  2. android
  3. c#
  4. .net
  5. javascript
  6. php
  7. jquery
  8. html
  9. sql

Spring Security sem autenticação

Tenho um sistema que já faz a autenticação do usuário, e controla o acesso à páginas que exige autenticação, preciso usar o spring security para controlar acesso as páginas por regras de usuário e para controlar acesso a determinados recursos, como por exemplo um usuário ter permissão apenas para listar registros e não ter para excluir registros.

Tentei implantar um login com spring securiy e passar a responsabilidade da autenticação para a minha a classe que cuida do login no sistema, fazendo uma implementação do UserDetailsService, mas não obtive sucesso.

Os tutorias que encontrei na web abordam a autenticação e dão pouca atenção para a autorização, alguém sabe de algum link interessante para a minha necessidade?

O meu código está assim:

web.xml

 <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/faces-config.xml</param-value>
    </context-param>
    <display-name>Ultracar Web</display-name>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>
    <!--<context-param>
     <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
     <param-value>-1</param-value>
    </context-param>
    -->
    <welcome-file-list>
        <welcome-file>Principal/index.xhtml</welcome-file>
    </welcome-file-list>

    <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>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml            
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <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>

spring-security:

<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="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.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="Principal/index*" access="permitAll" />
        <intercept-url pattern="/Principal/*" access="permitAll"/>

        <form-login login-page="/Principal/index.xhtml"        
                             default-target-url="/"
                             authentication-failure-url="/"/>
        <logout logout-success-url="/" />
    </http>

<beans:bean id="customUserDetails" class="br.com.ultracar.ultracarweb.spring.security.UserDetailsServiceImpl" />

<authentication-manager>
    <authentication-provider user-service-ref="customUserDetails" />  
</authentication-manager>    

</beans:beans>ode here

pagina de login:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <link rel="SHORTCUT ICON" href="../Imagens/logo.png"/>
    </h:head>
    <h:body>
        <ui:composition template="./../Principal/template_inicio.xhtml">            
            <ui:define name="content">
                <div class="slider">
                    <div class="container" style="padding: 10px;">
                        <div class="col-lg-9 col-xs-9 col-sm-9">
                            <ui:include src="slider.xhtml"/>
                        </div>

                        <div class="col-lg-3 col-xs-3 col-sm-3" style="padding: 17px 0;background-color: #B3B3B3;">
                            <img class="img-responsive" style="margin: 0 auto" src="#{request.contextPath}/Imagens/logo.png" />

                            <h:form id="frmLogin" class="form-group" >

                                    <div class="row">                                    
                                        <div class="col-lg-12 col-xs-12 col-sm-12 ">
                                            <h:outputLabel style="color: #303030;" value="#{Utils.getStrLanguage('Usuario')}:" />
                                        </div>
                                    </div>

                                    <div class="row">
                                        <div class="col-lg-12 col-xs-12 col-sm-12">
                                            <p:inputText value="#{MBControl.login}" required="true"
                                                         style="width: 100%;-moz-box-shadow: none !important; -webkit-box-shadow: none !important; 
                                                         box-shadow: none !important; -moz-border-radius: 0 !important; 
                                                         -webkit-border-radius: 0 !important; border-radius: 0 !important;"
                                                         requiredMessage="#{Utils.getStrLanguage('Usuario_requerido')}"/>
                                        </div>                                    
                                    </div>

                                    <div class="row">
                                        <div class="col-lg-12 col-xs-12 col-sm-12">
                                            <h:outputLabel style="color: #303030;" value="#{Utils.getStrLanguage('Senha')}:" />
                                        </div>                                    
                                    </div>

                                    <div class="row">
                                        <div class="col-lg-12 col-xs-12 col-sm-12">
                                            <p:password value="#{MBControl.senha}" required="true" id="txtSenha" styleClass="reset-style"
                                                        style="width: 100%;-moz-box-shadow: none !important; -webkit-box-shadow: none !important; 
                                                        box-shadow: none !important; -moz-border-radius: 0 !important; 
                                                        -webkit-border-radius: 0 !important; border-radius: 0 !important;"
                                                        requiredMessage="#{Utils.getStrLanguage('Senha_requerida')}"/>
                                        </div>                                   
                                    </div>

                                    <div class="row" style="margin-top: 15px;">
                                        <div class="col-lg-4 col-xs-6 col-sm-12">
                                            <p:commandLink id="btnLogin" styleClass="btn button-green" ajax="false" action="#{MBControl.logar()}" 
                                                           update="frmLogin" value="#{Utils.getStrLanguage('Login')}" style="border-radius: 0 !important;"/>
                                        </div>                                                     
                            </h:form>
                        </div>                        
                    </div> 
                </div>
            </ui:define>
        </ui:composition>
    </h:body>
</html>

Classe de login:

public class MBControl {
    public String logar() {
        FacesContext contexto = FacesContext.getCurrentInstance();
        HttpSession sessao = (HttpSession) contexto.getExternalContext().getSession(false);
        Session session = FacesContextUtil.getRequestSession();
        Usuario usuario = null;
        boolean senhaOk = false;

        try
        {
            usuario = (Usuario) session.createCriteria(Usuario.class)
                                                              .add(Restrictions.eq("usuario",login))
                                                              .list().get(0);
            senhaOk = (usuario.getSenha().equals(senha));
        }catch(Exception ex){
            System.out.println(ex.toString());
        }

        if (usuario!=null && senhaOk){
            if (!usuario.getAtivo()){
                warning(null,Utils.getStrLanguage("Usuario_nao_ativo")+"!",FacesMessage.SEVERITY_FATAL);
                return "sair";
            }
            sessao.setAttribute("login", login);
            sessao.setAttribute("senha", new Utils().SHA1(senha));
            MBControl.matriz = usuario.getIdMatriz();
            userDetails.loadUserByUsername(usuario.getUsuario());
            return "sucesso";
        }else{
            warning(null,Utils.getStrLanguage("Usuario_senha_invalidos")+"!",FacesMessage.SEVERITY_FATAL);
            return "sair";
        }
    }
}

Não sei como fazer o spring chamar minha classe de login, e depois como controlar as permissões através do spring.

Desde já agradeço á todos pela ajuda.

Atualizando: Obtive alguma evolução no problema seguindo a dica do @elioengcomp sobre usar a tag authorize, foi necessário incluir o um arquvivo xml em WEB-INF.

springsecurity.taglib.xml :

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://www.springframework.org/security/tags</namespace>
    <tag>
        <tag-name>authorize</tag-name>
        <handler-class>org.springframework.faces.security.FaceletsAuthorizeTagHandler</handler-class>
    </tag>
    <function>
        <function-name>areAllGranted</function-name>
        <function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
        <function-signature>boolean areAllGranted(java.lang.String)</function-signature>
    </function>
    <function>
        <function-name>areAnyGranted</function-name>
        <function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
        <function-signature>boolean areAnyGranted(java.lang.String)</function-signature>
    </function>
    <function>
        <function-name>areNotGranted</function-name>
        <function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
        <function-signature>boolean areNotGranted(java.lang.String)</function-signature>
    </function>
    <function>
        <function-name>isAllowed</function-name>
        <function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
        <function-signature>boolean isAllowed(java.lang.String, java.lang.String)</function-signature>
    </function>
</facelet-taglib>

inclui o seguinte bloco no web.xml :

<context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
    </context-param>

Fiz uma implementação teste de UserDetailsService, UserDetailsServiceImp:

@Service("userService")
public class UserDetailsServiceImpl implements UserDetailsService {  


@Override  
public UserDetails loadUserByUsername( String username ) throws UsernameNotFoundException{     

    FacesContext contexto = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession) contexto.getExternalContext().getSession(false);
    boolean enabled = false;  
    boolean credentialsNonExpired = false;  
    boolean accountNonExpired = false;  
    boolean accountNonLocked = false;
    Authority autorizacao = new Authority("ROLE_ADMINISTRADOR");   

    Set<Authority> roles = new HashSet<Authority>();
    enabled = true;  
    credentialsNonExpired = true;  
    accountNonExpired = true;  
    accountNonLocked = true;
    roles.add(autorizacao);
    String senha = session.getAttribute("senha").toString();   

    User springUser = new User(username, senha, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, roles);      

    return springUser;   
  }    

}

E também fiz uma classe que implementa a interface GrantedAuthority:

Authority.java :

public class Authority implements GrantedAuthority{

    private String authority;

    public Authority(String authority){

        this.authority = authority;
    }

    @Override
    public String getAuthority() {

        return authority;
    }

    public void setAuthority(String authority) {
        this.authority = authority;
    }    
}

Usando as tags authorize consegui bloquear a acesso em minhas páginas xhtml como por exemplo:

<sec:authorize access="hasRole('ROLE_ADMINISTRADOR')" >
                                    <h:commandLink action="#{ConsultaProdutoBBeans.novoProduto()}" 
                                                   title="#{Utils.getStrLanguage('Novo')} #{Utils.getStrLanguage('produto')}">
                                        <p:graphicImage value="/Imagens/add-file-24.png"/>
                                    </h:commandLink>
                                </sec:authorize>

O problema que mesmo quando adiciono a role ROLE_ADMINISTRADOR em UserDetailsService o acesso ao recurso não é liberado, eu estou chamando a UserDetailsService em meu método próprio de login, e anotei esta classe como minha no xml, o que ainda preciso fazer?

  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do GUJ!

2 respostas

Não é a resposta que estava procurando? Procure outras perguntas com as tags spring-security ou faça a sua própria pergunta.