Spring security 3. Autorização dinamica

29 respostas
A

Olá pessoal.
Estou numa aplicação e com uma duvida cruel sobre Spring Security.
Todo material ensina a colocar as autorizações no XML, fixo. Tipo

<http access-denied-page="/accessDenied.xhtml"
		access-decision-manager-ref="accessDecisionManager">
		<intercept-url pattern="/css/**"
			filters="none" access="ROLE_USER, ROLE_ADMIN" />

...

No meu caso, preciso que essas intercept-url, seja colocada no banco e na autorizacao, esse usuario passe a ter ou não autorizaçao para as urls. Qual classe eu implemento ou extendo para este fim?
Alguem pode me ajudar?

29 Respostas

F

http://static.springsource.org/spring-security/site/faq/faq.html#faq-dynamic-url-metadata

A

Me ajudou um pouco, já que esse tópico mostra a interface que devo implementar para autorizar dinamicamente… mas cade o xml com as configurações desse filtro e como eu lanço as urls em código e não

<http access-denied-page="/accessDenied.xhtml">
		<intercept-url pattern="/ideiasecurityad/css/**"
			filters="none" access="ROLE_USER, ROLE_ADMIN" />
		<intercept-url pattern="/ideiasecurityad/js/**" filters="none"
			access="ROLE_USER, ROLE_ADMIN" />
		<intercept-url pattern="/**" access="ROLE_USER, ROLE_ADMIN" />

		<intercept-url pattern="/login.jsf" filters="none"
			access="IS_AUTHENTICATED_ANONYMOUSLY" />
		<intercept-url pattern="/images/**" filters="none" /> 
.....

Ou, seja, no xml. O tópico lá é muito vazio. Queria um exemplo. Alguem consegue?:

A

Ninguem?

A

Onde eu chamdo Esse filtro no application-context.xml ?

P

Amigo estou com a mesma necessidade e ainda não encontrei a solução.

A

Já resolvi… posto pra você a solulção depois. É que eu cheguei agora da rua, tava tomando umas rsrrs… mas prometo te passar a solução.

P

Ok fico aguardando.

A

Bom, vamos lá.
Vou partir do pressuposto que vc já está na metade do caminho, como eu estava. Só não sabia como fazer dinamicamente as autorizações, pegando as permissões do BD ok? Se eu estiver errado, me corrija e tentamos resolver seu problema aqui.
Eu fazia tudo certo, mas nao sabia como tirar lá as tag <http><intercept-url> do application-context.xml.
Vou explicar mais ou menos como isso funciona. O UserDetailsImpl.java, é o coração do lance. Ele é colocado na sessão pelo Spring e nele vc terá que implementar o método public Collection<GrantedAuthority> getAuthorities() . Aí que está o segredo do negócio. No meu caso eu tenho Usuarios que tem Papeis (Admin, professor, operador, etc). Tem tbm a tabela Permissoes que é um fk de Papeis e um outro de Funcionalides (que são as urls. Ex: xx/adafsd/xxx.jsf). Lembrando que na tabela Funcionalidade eu tenho uma coluna chamada menu = 0 ou 1. Se for 1, vou usar essa fucionalidade pra montar meu menu dinamicamente, que posso explicar como faço em outro capitulo :smiley: :smiley: :smiley: .
Bom, vc criando uma lista de GrantedAuthority e retornando no metodo citado acima, vc já tems os papeis daquele cara na sessão. Agora, resta vc implementar o método public List<ConfigAttribute> getAttributes(Object object) { do seu FilterInvocationSecurityMetadataSource e tudo ficará bem. Esse metodo tbm retorna Papeis, tipo. Toda vez que vc clica numa url, esse método é chamado para verificar o papel que a aquela funcionalidade permite. Assim, se esse papel retornado estiver no seu UserDetailsImpl.java, vc automaticamente acessará, do contrário, será barrado.

Vou explanar um pouco meus dois metodos. No decorrer, sei que vao surgir muitas duvidas como eu mesmo tive, mas estaria aqui à disposição:

UserDetailsImpl.getAuthorities()

List<PapelVO> listPapeis = new ArrayList<PapelVO>();

			if (usuarioVO.getPapeis().length > 0) {
				listPapeis.addAll(Arrays.asList(usuarioVO.getPapeis()));
			}
for (Iterator<PermissaoVO> iterator = permissoes.iterator(); iterator
					.hasNext();) {
				PermissaoVO permissao = (PermissaoVO) iterator.next();

				List<Role> roles = new ArrayList<Role>();

				String[] arrayPapeis = permissao.getPapeis();
				for (int i = 0; i < arrayPapeis.length; i++) {
					Role role = new Role(
							"ROLE_" + arrayPapeis[i].toUpperCase(),
							arrayPapeis[i]);
					roles.add(role);
				}

				SecureResource secObject = new SecureResource(
						permissao.getObjeto(),
						SecurityConstants.RESOURCE_TYPE_FI);
				String url = new String(permissao.getObjeto());
				int firstQuestionMarkIndex = url.indexOf("?");

				if (firstQuestionMarkIndex != -1) {
					url = url.substring(0, firstQuestionMarkIndex);
				}

return this.authorities;

Olha, no Filtro, vc faz do teu jeito, pegando as urls do seu banco e verificando se essa url tem Permissao, ou seja se tem num hash que vc coloca la no UserDetailsImpl. Se sim, vc vai contatenando num Stringbuffer assim “ROLE_X, ROLE_Y” e retorna da seguinta forma: return SecurityConfig.createListFromCommaDelimitedString(Seu String), caso nao encontre no HashMap do UserDetailsImpl, retorno return SecurityConfig.createListFromCommaDelimitedString(“ROLE_INVALIDA”). Ele vai barrar o usuário com isso.
Bom, tem muito coisa a ser feita ainda, tipo as Urls padroes, que sáo os js, as urls do framework que vc usa, etc. mas Se vc conseguir barrar dessa forma, já é um bom começo e eu estou aqui pra te ajudar. Qualquer coisa posta.
Abraços.

P
@Override
    protected UserDetails retrieveUser(String username,
            UsernamePasswordAuthenticationToken authentication)  {

        String password = (String) authentication.getCredentials();
        if (!StringUtils.hasText(password)) {
            throw new BadCredentialsException("Por favor digite sua senha");
        }
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        try {

            Usuario usuario = new Usuario();
			try {
				usuario = (Usuario) ejbFacade.buscarPorNamedQuery("Usuario.BuscaUsersByUsernameEqualsPasswordEquals", new Object[]{username, password});
			} catch (SefazException e) {
	        	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Sample error message", "Usuário inválido!"));  
				e.printStackTrace();
			}

            if (usuario != null) {
                usuario.setUltimoAcesso(usuario.getAcessoAtual());
                usuario.setAcessoAtual(new Date());
                try {
					ejbFacade.editar(usuario);
				} catch (SefazException e) {
		        	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Sample error message", "Usuário inválido!"));  
					e.printStackTrace();
				}
            }

            if (usuario != null && usuario.getPapel().size() > 0) {
                Iterator<Papel> papeis = usuario.getPapel().iterator();

                while (papeis.hasNext()) {
                    Papel papel = papeis.next();
                    authorities.add(new GrantedAuthorityImpl(papel.getNome()));
                }
                
            } else {
                throw new InsufficientAuthenticationException("Usuario sem permissao!");
            }

        } catch (EmptyResultDataAccessException e) {    
        	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Sample error message", "Usuário ou senha inválidos!"));          
            throw new BadCredentialsException("Usuario ou senha invalidos!");
          } catch (EntityNotFoundException e) {
        	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Sample error message", "Usuário inválido!"));  
            throw new BadCredentialsException("Usuario invalido");
        } catch (NonUniqueResultException e) {
        	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Sample error message", "Usuário não único, contate o suporte!"));  
            throw new BadCredentialsException("Usuario nao unico, contate o suporte");
        }
        
        return new User(username, password, true, true, true, true, authorities);
    }

Aqui está meu método que verifica as permissões do usuário e coloca na sessão, estou tentando entender o seu código, tenho algumas dúvidas:
Você não usa o poderia postar o seu applicationContext-security.xml não entendi como ficou lá.

Obrigado pela atenção

A
<?xml version="1.0" encoding="UTF-8"?>

<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.0.3.xsd">

	<!--<global-method-security secured-annotations="enabled" /> --> <!-- Habilita anotações nos seus beans -->
	<authentication-manager alias="authenticationManager">
		<authentication-provider user-service-ref="userDetailsServiceImpl" />
	</authentication-manager>

	<beans:bean id="anonymousAuthFilter"
		class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
		<beans:property name="key" value="foobar" />
		<beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
	</beans:bean>

	<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
		<beans:constructor-arg value="/login.jsf" />
		<!-- URL redirected to after logout -->
		<beans:constructor-arg>
			<beans:list>
				<beans:bean	class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
			</beans:list>
		</beans:constructor-arg>
	</beans:bean>

	<!-- Sua classe customizada para validar o seu usuario pelo banco -->
	<beans:bean id="segurancaEventListener"
		class="br.com.ideiadigital.ideiasecurityad.utils.seguranca.SegurancaEventListener">
	</beans:bean>
	<beans:bean id="springSecurityFilterChain"
		<filter-chain-map path-type="ant">
			<filter-chain filters="anonymousAuthFilter" pattern="/adf/**" />
			<filter-chain filters="anonymousAuthFilter" pattern="/images/**" />
			<filter-chain filters="anonymousAuthFilter" pattern="/css/**" />
			<filter-chain filters="anonymousAuthFilter" pattern="/js/**" />
			<filter-chain filters="anonymousAuthFilter" pattern="/skins/**" />
			<filter-chain pattern="/login.jsf" filters="anonymousAuthFilter" />
			<filter-chain pattern="/a4j_3_2_0-SNAPSHOTorg/**"
				filters="anonymousAuthFilter" />
			<filter-chain
				pattern="/a4j_3_2_0-SNAPSHOTorg.richfaces.renderkit.html.images.InputBackgroundImage/**"
				filters="anonymousAuthFilter" />
			<filter-chain
				pattern="/a4j_3_2_0-SNAPSHOTorg.richfaces.renderkit.html.images.ButtonBackgroundImage/**"
				filters="anonymousAuthFilter" />
			<filter-chain pattern="/acessoNegado.jsf" filters="anonymousAuthFilter" />
			<filter-chain pattern="/j_spring_security_check"
				filters="authenticationProcessingFilter" />
			<filter-chain pattern="/**"
				filters="logoutFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
		</filter-chain-map>
	</beans:bean>

	<beans:bean id="authenticationProcessingFilter"
		class="org.springframework.security.web.authentication.AuthenticationProcessingFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
	</beans:bean>

	<beans:bean id="httpSessionContextFilter"
		class="org.springframework.security.web.context.HttpSessionContextIntegrationFilter" />

	<beans:bean id="contextSource"
		class="org.springframework.ldap.core.support.LdapContextSource">
		<beans:property name="url" value="ldaps://10.1.11.78:636" />
		<beans:property name="base" value="dc=ideiasecurity" />
		<beans:property name="userDn" value="desenvolvimento" />
		<beans:property name="password" value="teste123" />
	</beans:bean>

	<beans:bean id="ldapAuthProvider"
		class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
		<beans:constructor-arg ref="ldapBindAuthenticator" />
		<beans:constructor-arg ref="ldapAuthoritiesPopulator" />
	</beans:bean>

	<beans:bean id="ldapBindAuthenticator"
		class="org.springframework.security.ldap.authentication.BindAuthenticator">
		<beans:constructor-arg ref="contextSource" />
		<beans:property name="userSearch" ref="ldapSearchBean" />
	</beans:bean>

	<beans:bean id="ldapSearchBean"
		class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
		<beans:constructor-arg value="" /><!-- user-search-base -->
		<beans:constructor-arg value="(uid={0})" /> <!-- user-search-filter -->
		<beans:constructor-arg ref="contextSource" />
	</beans:bean>

	<beans:bean id="userDetailsServiceImpl"
		class="br.com.ideiadigital.ideiasecurityad.web.seguranca.UserDetailServiceImpl">
	</beans:bean>

	<beans:bean id="ldapAuthoritiesPopulator"
		class="org.springframework.security.ldap.authentication.UserDetailsServiceLdapAuthoritiesPopulator">
		<beans:constructor-arg ref="userDetailsServiceImpl" />
	</beans:bean>
	<beans:bean id="accessDecisionManager"
		class="org.springframework.security.access.vote.AffirmativeBased">
		<beans:property name="decisionVoters">
			<beans:list>
				<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
				<beans:bean
					class="org.springframework.security.access.vote.AuthenticatedVoter" />
			</beans:list>
		</beans:property>
	</beans:bean>

	<beans:bean id="authorizationService"
		class="br.com.ideiadigital.ideiasecurityad.service.seguranca.AuthorizationServiceImpl">
		<beans:property name="authDAO">
			<beans:ref local="authDAO" />
		</beans:property>
	</beans:bean>

	<beans:bean id="authDAO"
		class="br.com.ideiadigital.ideiasecurityad.entity.seguranca.AuthorizationDaoImpl"></beans:bean>

	<beans:bean id="databaseFilter"
		class="br.com.ideiadigital.ideiasecurityad.web.seguranca.FilterCustomInvocationSecurityMetadataSource">
		<beans:property name="authorizationService">
			<beans:ref local="authorizationService" />
		</beans:property>
	</beans:bean>

	<beans:bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
		<beans:property name="accessDecisionManager" ref="accessDecisionManager"></beans:property>
		<beans:property name="securityMetadataSource" ref="databaseFilter"></beans:property>
		<beans:property name="validateConfigAttributes" value="true"></beans:property>
	</beans:bean>

	<beans:bean id="exceptionTranslationFilter"
		class="org.springframework.security.web.access.ExceptionTranslationFilter">
		<beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
		<beans:property name="accessDeniedHandler" ref="accessDeniedHandler" />
	</beans:bean>

	<beans:bean id="authenticationEntryPoint"
		class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
		<beans:property name="loginFormUrl" value="/login.jsf" />
	</beans:bean>

	<beans:bean id="accessDeniedHandler"
		class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
		<beans:property name="errorPage" value="/acessoNegado.jsf" />
	</beans:bean>
</beans:beans>

Não usa , já que você está usando dinâmicamente as urls. Essas tags seria pra url fixa. Dá uma observada no FilterChainProxy. Lá tem as urls que vc precisa pra liberar pelo menos a pagina de log. Mas, como te falei, eu estou usando richfacs e trinidad, por isso o seu pode ser diferente. pode não utilizar a url /a4j_3_2_0-SNAPSHOTorg.richfaces.renderkit.html.images.ButtonBackgroundImage/** por exemplo.

Qualquer dúvida estou aqui.

P

Ok deixa eu ver se consigo me explicar para ver se consigo fazer também, eu tenho as seguintes classes no meu projeto: usuário, papel, atividade onde a atividade contém a URL que é permitida para um determinado papel e usuário pode ter vários papeis assim como atividade pode ter vários papeis também, até ai tudo bem dai tenho uma outra classe que estende AbstractUserDetailsAuthenticationProvider que contem o método que postei ai e la eu busco o usuário e seto os papeis dele pra a seção, e a atividade até o momento é burra ela só consegue saber quais são as URLs disponíveis para o papel do usuário, tipo monta o menu mas não intercepta a URL. Bom isso acho q vc já tinha entendido né.

Agora não consigo imaginar onde colocar o método que vai interceptar a URL que foi solicitada.

P
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd">


	<!-- HTTP security configurations -->
    <http auto-config="true" use-expressions="true" access-denied-page="/login.jsf">
        <intercept-url pattern="/pages/atividade/**" access="hasAnyRole('Desenvolvedor')"/>
        <intercept-url pattern="/pages/municipio/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfeContribuinte/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfeOrgaoGerador/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfePedidoDeCredenciamento/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfeRegimeFiscal/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfeSituacaoCredenciado/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/nfeSituacaoCredenciamento/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/papel/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/pessoaJuridica/**" access="hasAnyRole('Administrador','Desenvolvedor','Operador','Gestor')"/>
        <intercept-url pattern="/pages/usuario/**" access="hasAnyRole('Administrador','Desenvolvedor')"/>
        <intercept-url pattern="/pages/nfecancelamentoextratemporaneo/**" access="hasAnyRole('Administrador','Desenvolvedor','Gestor')"/>
        <intercept-url pattern="/pages/main.jsf" access="isAuthenticated()"/>
        <intercept-url pattern="/template/menu.xhtml" access="isAuthenticated()"/>
        <intercept-url pattern="/index.jsf" access="isAuthenticated()"/>
        <form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?erro=true"/>
    </http> 
    
    <beans:bean name="NfeAuthenticationProvider" class="gov.sefaz.ms.nfe.gerencial.util.NfeGerencialAuthenticationProvider" /> 
    
    <authentication-manager alias="authenticationManager">  
        <authentication-provider ref="NfeAuthenticationProvider"/>  
    </authentication-manager>
    
</beans:beans>

Segue meu applicationContext-security.xml

A

Vamos lá:

1- Retira sua tag junto com
2 - implementar um filterInterceptor extendendo FilterInvocationSecurityMetadataSource;
Um exemplo aqui:

public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    public List<ConfigAttribute> getAttributes(Object object) {
      FilterInvocation fi = (FilterInvocation) object;
        String url = fi.getRequestUrl();
        String httpMethod = fi.getRequest().getMethod();
        List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();

        // Lookup your database (or other source) using this information and populate the
        // list of attributes

        return attributes;
    }

    public Collection<ConfigAttribute> getAllConfigAttributes() {
      return null;
    }

    public boolean supports(Class<?> clazz) {
      return FilterInvocation.class.isAssignableFrom(clazz);
    }
  }

3- Coloca no application-security.xml

<beans:bean id="databaseFilter"
		class="seupacote.MyFilterSecurityMetadataSource"/>

<beans:bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
                 <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
		<beans:property name="accessDecisionManager" ref="accessDecisionManager"></beans:property>
		<beans:property name="securityMetadataSource" ref="databaseFilter"></beans:property>
		<beans:property name="validateConfigAttributes" value="true"></beans:property>
	</beans:bean>

Agora o segredo no mesmo application-context.xml

<beans:bean id="springSecurityFilterChain"
		class="org.springframework.security.web.FilterChainProxy"> 	
<filter-chain-map path-type="ant">
<filter-chain pattern="/**"
				filters="logoutFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
</filter-chain-map>
	</beans:bean>

O <filter-chain pattern="/" filters=xxxxx,xxx diz ao spring que todas as urls da sua aplicação ("/") serao interceptadas pelo logoutFilter, exceptionTranlationFilter e depois pelo filterSecurityInterceptor, nessa sequencia… O filterSecurityInterceptor tem por sua vez o securityMetadataSource que é a sua implementação do FilterInvocationSecurityMetadataSource. Coloca um breakpointer em MyFilterSecurityMetadataSource.getAttributes e vc vai ver ele interceptando cada url.

P
Olha como ficou meu codigo agora
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd">

    
    <beans:bean id="databaseFilter" class="gov.sefaz.ms.nfe.gerencial.util.MyFilterSecurityMetadataSource"/>

	<beans:bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
                 <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
		<beans:property name="accessDecisionManager" ref="accessDecisionManager"></beans:property>
		<beans:property name="securityMetadataSource" ref="databaseFilter"></beans:property>
		<beans:property name="validateConfigAttributes" value="true"></beans:property>
	</beans:bean>
	
    <beans:bean id="accessDecisionManager"  
        class="org.springframework.security.access.vote.AffirmativeBased">  
        <beans:property name="decisionVoters">  
            <beans:list>  
                <beans:bean class="org.springframework.security.access.vote.RoleVoter" />  
                <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />  
            </beans:list>  
        </beans:property>  
    </beans:bean>  
    
    <beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> 	
			<filter-chain-map path-type="ant">
			<filter-chain pattern="/**" filters="logoutFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
			</filter-chain-map>
	</beans:bean>
        
    <beans:bean name="NfeAuthenticationProvider" class="gov.sefaz.ms.nfe.gerencial.util.NfeGerencialAuthenticationProvider" /> 

    <authentication-manager alias="authenticationManager">  
        <authentication-provider ref="NfeAuthenticationProvider"/>  
    </authentication-manager>

</beans:beans>
package gov.sefaz.ms.nfe.gerencial.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    public List<ConfigAttribute> getAttributes(Object object) {
      FilterInvocation fi = (FilterInvocation) object;
        String url = fi.getRequestUrl();
        String httpMethod = fi.getRequest().getMethod();
        List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();

        // Lookup your database (or other source) using this information and populate the
        // list of attributes

        return attributes;
    }

    public Collection<ConfigAttribute> getAllConfigAttributes() {
      return null;
    }

    public boolean supports(Class<?> clazz) {
      return FilterInvocation.class.isAssignableFrom(clazz);
    }
  }

Erro que recebo ao levantar a aplicação

GRAVE: PWC1306: Startup of context /nfe-gerencial-web failed due to previous errors
GRAVE: PWC1305: Exception during cleanup after start failed
org.apache.catalina.LifecycleException: PWC2769: Manager has not yet been started
	at org.apache.catalina.session.StandardManager.stop(StandardManager.java:874)
	at org.apache.catalina.core.StandardContext.stop(StandardContext.java:5571)
	at com.sun.enterprise.web.WebModule.stop(WebModule.java:527)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5384)
	at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)

GRAVE: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5389)
	at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:378)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:161)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
	at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4750)
	at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:550)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5366)
	... 38 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1083)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
	... 60 more

AVISO: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:921)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)

GRAVE: Exception while invoking class com.sun.enterprise.web.WebApplication start method
java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:138)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)

GRAVE: Exception while loading the app

INFO: closing
INFO: closing
INFO: closing
GRAVE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in file [D:\glassfish3\glassfish\domains\domain1\applications\nfe-gerencial-ear\nfe-gerencial-web-1.0-SNAPSHOT_war\WEB-INF\classes\META-INF\spring\applicationContext-security.xml]: Cannot resolve reference to bean 'logoutFilter' while setting bean property 'filterChainMap' with key [Root bean: class [org.springframework.security.web.util.AnyRequestMatcher]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [0]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'logoutFilter' is defined
A

retira os filtros logoutFilter,exceptionTranslationFilter e do seu filterChain e deixa por enquanto o filtro filterSecurityInterceptor somente.

ficando assim:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">       
            <filter-chain-map path-type="ant">  
            <filter-chain pattern="/**" filters="filterSecurityInterceptor" />  
            </filter-chain-map>  
    </beans:bean>

mas os filtros que vc vai retirar vao ser preciso colocar no futuro… prq logoutFilter é pra ele saber o que fazer quando fizer logout…portanto, sugiro que dê uma olhada num post anterior que fiz com todos esses filtros do application-context.xml.

P

Percebi esse erro e coloquei os filtros conforme seu xml.

P

Perfect o MyFilterSecurityMetadataSource.getAttributes foi interceptou a url. Agora tenho q entender o resto : )

A

Ótimo. Agora vc pega a url… procura no seu banco, ve se os papeis que ela tem e retorna no metodo. Bem parecido com o getAutorities() la do userDetailsImpl… O spring pega essas duas listas e compara… se vc tiver autorizacao naquela url, vc passa. Dá uma olhada mais ou menos no meu. Sendo que quando ele retorna ROLE_INVALIDA ele bloqueia a url.

public List<ConfigAttribute> getAttributes(Object object) {
		if ((object == null) || !this.supports(object.getClass())) {
			throw new IllegalArgumentException(
					"Object must be a FilterInvocation");
		}

		String url = ((FilterInvocation) object).getRequestUrl();
		String method = ((FilterInvocation) object).getHttpRequest()
				.getMethod();
		objFilter = (FilterInvocation) object;
		
		return lookupAttributes(url, method);
	}

public final List<ConfigAttribute> lookupAttributes(String url,
			String method) {
		
		HttpServletRequest objRequest = null;
		
		if (objFilter!=null) { 
			objRequest = objFilter.getHttpRequest();
		}
		

		StringBuilder rolesBuilder = new StringBuilder();
		rolesBuilder.append("IS_AUTHENTICATED_ANONYMOUSLY");
		Object objContext = null;
		if(SecurityContextHolder.getContext().getAuthentication() != null)
			objContext = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

		if (objContext instanceof UserDetailsImpl) {
			objSessaoUsuario = (UserDetailsImpl)objContext;
		} else 
			objSessaoUsuario = null;
		
		int firstQuestionMarkIndex = url.indexOf("?");

		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}
		
		int x = 0;
		do {
			firstQuestionMarkIndex = url.indexOf(urlsPadrao[x]);
			x++;
		} while ((x < urlsPadrao.length) && (firstQuestionMarkIndex==-1));
		
		if (firstQuestionMarkIndex != -1) {
			url = urlsPadrao[x-1]+"**";
		}
		
    	SecureResource secureObject = null;
		List<Role> secureObjectRoles = null;

		if (objSessaoUsuario!=null) { 
        	secureObject = objSessaoUsuario.getSecureObject(url);
        } 

		if (secureObject == null) {
	        secureObject = authorizationService.getSecureObject(url);
			if (secureObject == null)// if secure object not exist in database
				return SecurityConfig.createListFromCommaDelimitedString("ROLE_INVALIDA");
		}

		if (objSessaoUsuario!=null) {
			secureObjectRoles = objSessaoUsuario.getSecureObjectRoles(secureObject);
			PermissaoVO permissao = objSessaoUsuario.getPermissao(url);
			if (objRequest!=null && permissao!=null && permissao.getAcoes().length>0) {
				String[] acoes = permissao.getAcoes();
				for (int i = 0; i < acoes.length; i++) {
					objRequest.removeAttribute(acoes[i].toString());
					objRequest.setAttribute(acoes[i].toString(), "true");		
				}
			}
        } 
		
		if (secureObjectRoles != null && !secureObjectRoles.isEmpty()) {
			for (int i = 0; i < secureObjectRoles.size(); i++) {
				Role sor = (Role) secureObjectRoles.get(i);
				rolesBuilder.append(","+sor.getName());

			}

			return SecurityConfig.createListFromCommaDelimitedString(rolesBuilder.toString());
		} else {
			secureObjectRoles = authorizationService.getSecureObjectRoles(secureObject);
			if (secureObjectRoles != null && !secureObjectRoles.isEmpty()) {
				for (int i = 0; i < secureObjectRoles.size(); i++) {
					Role sor = (Role) secureObjectRoles.get(i);
					rolesBuilder.append(","+sor.getName());

				}

				return SecurityConfig.createListFromCommaDelimitedString(rolesBuilder.toString());
			}
		}

	return SecurityConfig.createListFromCommaDelimitedString("ROLE_INVALIDA");
	}
P

O seria esse “objFilter” eo “lookupAttributes” que vc usa ai no metodo?

A

objFilter é o valor que entra no parametro getAttributes(Object object) que é um FilterInvocation. Dá uma olhada no metodo. o Lookups foi só pra dividir em dois metodos. prq a versao antigo do acegi usava esse lookup, mas no meu caso estou chamando elel toda vez que é interceptado:

objFilter = (FilterInvocation) object;  
          
        return lookupAttributes(url, method);
P
Queria primeiro agradecer a sua paciência, bom como recupero o usuario na sessão tipo tenho um metodo que retorna o usuario corrente da sessão que esta retornando null e causando um erro o metodo é esse
private Usuario usuario = null;

    public Usuario getUsuarioCorrente() throws SefazException {
        if (usuario == null) {
            usuario = new Usuario();

            usuario = (Usuario) ejbFacade.buscarPorNamedQuery(
                    "Usuario.BuscaUsersByUsernameEquals",
                    new Object[]{SecurityContextHolder.getContext().getAuthentication().getName()});

        }
        return usuario;
    }
ele da esse erro aki
java.lang.NullPointerException
	at gov.sefaz.ms.nfe.gerencial.service.HomeMB.getUsuarioCorrente(HomeMB.java:38)
foi logo depois de implementado o filtro. :?
A
public static UserDetailsImpl getUsuarioLogado(){
		return (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
	}

Te retorna o usuario logado na sessao do spring.

P

adrian.gois:
public static UserDetailsImpl getUsuarioLogado(){ return (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); }
Te retorna o usuario logado na sessao do spring.

Oi vc me mostrar como vc usa o “UserDetailsImpl” não consegui resolver isso.

A

Mostra o erro ai.

P
adrian.gois:
Mostra o erro ai.

Não é bem um erro é q eu nao tenho essa classe UserDetailsImpl eu usava pra logar assim

<beans:bean name="NfeAuthenticationProvider" class="gov.sefaz.ms.nfe.gerencial.util.NfeGerencialAuthenticationProvider" /> 

    <authentication-manager alias="authenticationManager">  
        <authentication-provider ref="NfeAuthenticationProvider"/>  
    </authentication-manager>
A

Certo, dê uma olhada no meu UserDetailsServiceImpl que é o equivalente a sua classe ai:

@Override
	public UserDetails loadUserByUsername(String login)
			throws UsernameNotFoundException, DataAccessException {
		SegurancaService service = ServiceLocator.instance().getSegurancaService();
		UsuarioVO usuarioVO = null;
		if (login == ""){  
			throw new UsernameNotFoundException("Usu&#65533;rio esta em branco");
		}else{
			usuarioVO = service.getUser(login);	
			if (usuarioVO == null) {
				throw new UsernameNotFoundException("Usu&#65533;rio" + login + " n&#65533;o encontrado");
			}
		}
		System.out.println("PASSOU" + usuarioVO.getNome());
		UsuarioVO usuario = ServiceLocator.instance().getUsuarioService().loadUserById(usuarioVO.getIdUsuario());
		usuarioVO.setPapeis(usuario.getPapeis());
		return new UserDetailsImpl(usuarioVO);	
	}

Ele retorno uma UserDetailsImpl que eu implemento de org.springframework.security.core.userdetails.UserDetails

P

Será que não seria pedir muito se vc colocasse ai pra mim ver quais sao as classes e arquivos de xml vc tem?

Por exemplos eu tenho assim

-model
-----usuario
-----papel
-----atividade
--seguranca
------MyFilterSecurityMetadataSource
------UserDetailsAdapter
------UserDetailsServiceImpl

usuario
@NamedQueries({
    @NamedQuery(name = "Usuario.BuscaUsersByUsernameEqualsPasswordEquals", 
        query = "SELECT o FROM Usuario o WHERE o.username = :p0 AND o.password = :p1"),
    @NamedQuery(name = "Usuario.BuscaUsersByUsernameEquals", 
        query = "SELECT o FROM Usuario o WHERE o.username = :p0")
})
@Entity
@Table(name = "usuario")
public class Usuario extends gov.sefaz.utils.entidade.EntidadeBase {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;
    
    private String nome;
    
    private String username;
    
    private String password;
    
    private String email;
    
    private Boolean ativo;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ultimo_acesso")
    private Date ultimoAcesso;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "acesso_atual")
    private Date acessoAtual;
    
    @ManyToMany(cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
    private Set<Papel> papel = new HashSet<Papel>();

    @Version
    @Column(name = "versao")
    private Integer versao;
    
--.....
papel
@Entity
@Table(name = "papel")
public class Papel extends gov.sefaz.utils.entidade.EntidadeBase {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;
    
    @Column(name = "nome", nullable = false, length = 64)
    private String nome;

    @Version
    @Column(name = "versao")
    private Integer versao;

....
atividade
@NamedQueries({
    @NamedQuery(name = "Atividade.BuscaAtividadeByPapelEquals", 
                query = "SELECT o FROM Atividade o JOIN o.papel p WHERE p.id = :p0 ORDER BY o.ordem ASC"),
    @NamedQuery(name = "Atividade.BuscaAtividadeByRaiz", 
                query = "SELECT o FROM Atividade o JOIN o.papel p WHERE o.parente is null AND p.id = :p0 ORDER BY o.ordem ASC")
})
@Entity
@Table(name = "atividade")
public class Atividade extends gov.sefaz.utils.entidade.EntidadeBase {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "nome", nullable = false,length=64)
    private String nome;
    
    @Column(name = "url", length=255)
    private String url;
    
    @Column(name = "ordem", nullable = false,length=16)
    private String ordem;
    
    @ManyToOne
    @JoinColumn(name = "id_atv_pai", referencedColumnName = "id")  
    private Atividade parente;  

    @OneToMany(mappedBy = "parente", fetch=FetchType.EAGER)  
    private List<Atividade>  subAtividades;
    
    @ManyToMany
    private Set<Papel> papel = new HashSet<Papel>();

    @Version
    @Column(name="versao")
    private Integer versao;
MyFilterSecurityMetadataSource ficou assim
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private INfeGerencialBO ejbFacade;
	private FilterInvocation objFilter;

    
    public List<ConfigAttribute> getAttributes(Object object) {
    	if ((object == null) || !this.supports(object.getClass())) {  
            throw new IllegalArgumentException(  
                    "Object must be a FilterInvocation");  
        }  
  
        String url = ((FilterInvocation) object).getRequestUrl();  
        String method = ((FilterInvocation) object).getHttpRequest()  
                .getMethod();  
        objFilter = (FilterInvocation) object;  
          
        return lookupAttributes(url, method);  
    }
    
    

    private List<ConfigAttribute> lookupAttributes(String url, String method) {
		// TODO Auto-generated method stub
		return null;
	}



	public Collection<ConfigAttribute> getAllConfigAttributes() {
      return null;
    }

    public boolean supports(Class<?> clazz) {
      return FilterInvocation.class.isAssignableFrom(clazz);
    }
  }
UserDetailsAdapter
@Service("userDetailsAdapter")
public class UserDetailsAdapter {   

    private Long id;

    org.springframework.security.core.userdetails.User buildUserFromUserEntity(Usuario userEntity) {
        String username = userEntity.getUsername();
        String password = userEntity.getPassword();
        boolean enabled = userEntity.getAtivo();
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
         
         Iterator<Papel> papeis = userEntity.getPapel().iterator();

         while (papeis.hasNext()) {
             Papel papel = papeis.next();
             authorities.add(new GrantedAuthorityImpl(papel.getNome()));
         }

        /*this.id = userEntity.getId();*/

        org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        
        return user;
    }

    public Long getId() {
        return id;
    }

}
UserDetailsServiceImpl
package gov.sefaz.ms.nfe.gerencial.seguranca;

import gov.sefaz.ms.nfe.gerencial.bo.iface.INfeGerencialBO;
import gov.sefaz.ms.nfe.gerencial.entidade.Usuario;
import gov.sefaz.utils.exception.SefazException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

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


    @Autowired
    private INfeGerencialBO ejbFacade;
    
    @Autowired
    private UserDetailsAdapter userDetailsAdapter;

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        UserDetails userDetails = null;
        Usuario userEntity = null;
		try {
			userEntity = (Usuario) ejbFacade.buscarPorNamedQuery("Usuario.BuscaUsersByUsernameEquals", new Object[]{username});
		} catch (SefazException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        if (userEntity == null) {
          throw new UsernameNotFoundException("user not found");
        }
        userDetails = userDetailsAdapter.buildUserFromUserEntity(userEntity);

        return userDetails;
    }
}

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd">


 
    <beans:bean id="databaseFilter" class="gov.sefaz.ms.nfe.gerencial.seguranca.MyFilterSecurityMetadataSource"/>  
  
    <beans:bean id="filterSecurityInterceptor"  
        class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">  
                 <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>  
        <beans:property name="accessDecisionManager" ref="accessDecisionManager"></beans:property>  
        <beans:property name="securityMetadataSource" ref="databaseFilter"></beans:property>  
        <beans:property name="validateConfigAttributes" value="true"></beans:property>  
    </beans:bean>  
      
    <beans:bean id="accessDecisionManager"    
        class="org.springframework.security.access.vote.AffirmativeBased">    
        <beans:property name="decisionVoters">    
            <beans:list>    
                <beans:bean class="org.springframework.security.access.vote.RoleVoter" />    
                <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />    
            </beans:list>    
        </beans:property>    
    </beans:bean>    
    
    <beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">         
           <filter-chain-map path-type="ant">    
           <filter-chain pattern="/**" filters="filterSecurityInterceptor" />    
           </filter-chain-map>    
   </beans:bean>  
    
<authentication-manager alias="authenticationManager">  
        <authentication-provider user-service-ref="userDetailsServiceImpl" />  
    </authentication-manager>  
    
    <beans:bean id="userDetailsServiceImpl"  
        class="br.com.ideiadigital.ideiasecurityad.web.seguranca.UserDetailServiceImpl">  
    </beans:bean>  
 
</beans:beans>
A

Faz esse seu UserDetailsAdapter implementar UserDetails e implementa os metodos dessa classe. Os metodos que retornarem um boolean, vc retorna True. A única diferença do seu pra o meu é que eu implemento com outro nome: UserDetailsImpl e vc não implementou a classe UserDetails. Abraços.

C

Adrian, tudo bem ? Achei muito interessante seu exemplo e realmente não tem nada na net mostrando desta forma.

Estou tentando implementar este seu exemplo. Até a parte de interceptar as URLs está funcionando. A autenticação de usuários também.
Não está dando certo, quando eu coloco o método abaixo no UserDetailsImp, a parte de importar o SecureResource. Outra dúvida, o Role não é da library javax.management.relation.Role, é ?

public Collection<GrantedAuthority> getAuthorities() {
    	List<PapelVO> listPapeis = new ArrayList<PapelVO>();

		if (usuarioVO.getPapeis().length > 0) {
			listPapeis.addAll(Arrays.asList(usuarioVO.getPapeis()));
		}
		for (Iterator<PermissaoVO> iterator = permissoes.iterator(); iterator
				.hasNext();) {
			PermissaoVO permissao = (PermissaoVO) iterator.next();

			List<Role> roles = new ArrayList<Role>();

			String[] arrayPapeis = permissao.getPapeis();
			for (int i = 0; i < arrayPapeis.length; i++) {
				Role role = new Role(
						"ROLE_" + arrayPapeis[i].toUpperCase(),
						arrayPapeis[i]);
				roles.add(role);
			}

			SecureResource secObject = new SecureResource(
					permissao.getObjeto(),
					SecurityConstants.RESOURCE_TYPE_FI);
			String url = new String(permissao.getObjeto());
			int firstQuestionMarkIndex = url.indexOf("?");

			if (firstQuestionMarkIndex != -1) {
				url = url.substring(0, firstQuestionMarkIndex);
			}

return this.authorities;
    }
Criado 22 de setembro de 2011
Ultima resposta 8 de dez. de 2011
Respostas 29
Participantes 4