[RESOLVIDO] Spring Security - Atualizar Authorities / Permissões

4 respostas
O

Olá Pessoal!
Recentemente implementamos a segurança de um sistema (JSF + Primefaces) utilizando o spring security…
O sistema está funcionando perfeitamente, porém quando fazemos atualização de alguma ROLE/Permissões do usuário, até onde percebemos, o spring não interpreta está alteração em tempo de execução…
Diante do exposto pergunto-lhes…
Temos como fazer com que o spring atualize sua SQL / regras em tempo de execução ? Desta forma quando o usuário efetuasse a próxima requisição no servidor ele faria o Refresh das permissões…

Desde já agradeço.
:slight_smile: :slight_smile:

4 Respostas

M

Primeiramente qual a configuração que você esta usando?
Me antecipando eu sugiro a seguinte configuração para o seu Spring Security, desta forma você tem o controle da validação e assim fica mais facil customizar sem depender do comportamento padrão do Spring, segue:

<http use-expressions="true" auto-config="false" disable-url-rewriting="true">
                                    <session-management  session-fixation-protection="migrateSession" />
		                    <intercept-url pattern="/lista-produtos/*" access="hasRole('ROLE_USER')" />
		                    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
		                    <intercept-url pattern="/j_spring_security_check" />
		                   <intercept-url pattern="/**" requires-channel="http" />
			
         </http>

           <!-- Criação de alias para o seu provedor de autenticação -->
           <authentication-manager alias="authenticationManager">
				                     <authentication-provider ref="myAuthenticationProvider" />
	   		     </authentication-manager>
	
            <!-- Definicao do bean que irá receber as conexões e avaliar se o usuário tem ou não permissão para acesso -->
	    	         <beans:bean name="myAuthenticationProvider"
				                      class="br.com.meuprojeto.security.MyAuthenticationProvider">
	    	         </beans:bean>
		
	     	         <beans:bean id="passwordEncoder"
				                     class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
				                    <beans:constructor-arg index="0" value="256" />
	      	         </beans:bean>
Após esta configuração do contexto você pode fazer a implementação do seu provider, que seria algo assim:
@Component
public class MyAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

	@Autowired
	private ClientService clientService;

	
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
					throws AuthenticationException {
	}

	@Override
	protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) {
		String password = (String) authentication.getCredentials();
		
                if (!StringUtils.hasText(password)) {
			throw new BadCredentialsException("Entre com a senha por favor");
		}

		Client client = this.clientService.findByUsenameAndPassword(new Client(username, password));

		if (this.client == null) {
			throw new BadCredentialsException("Usuário invalido!");
		}

		authentication.setDetails(client);

                List<String> rolesForThisClient = clientService.findAllRoles(client); 
              
                List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

                foreach(String role in rolesForThisClient) {
                     authorities.add(new GrantedAuthorityImpl(role));
                }
		

		return new User(username, password, true, true, true, true, authorities);
	}
}
É isso ai, se você enviar suas configurações ficará mais facil encontrar uma solução.

abraço!

O

Olá mmaico,
Hoje está com a seguinte config:

- <b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="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.xsd">
<http auto-config="true" access-denied-page="/publico/acessoNegado.xhtml">
  <intercept-url pattern="/restrito/**" access="ROLE_TESTE" /> 
  <form-login login-page="/publico/login.xhtml" always-use-default-target="true" default-target-url="/restrito/index.xhtml" authentication-failure-url="/publico/index.xhtml?login_error=1" /> 
  <logout invalidate-session="true" /> 
  <remember-me /> 
  </http>
<authentication-manager>
<authentication-provider>
  <jdbc-user-service data-source-ref="financeiroDataSource" 

authorities-by-username-query="SELECT login, role FROM permissoes where login=?;" 

users-by-username-query="SELECT login, senha, status FROM login where login = ?" /> 
  </authentication-provider>
  </authentication-manager>
  </b:beans>

Você acha que se alterar o contexto para seu exemplo ele ira atualizar as permissões em tempo de execução ? Queremos que as modificações efetuadas no perfil reflitam a medida que o perfil de acesso for “atualizado”…

Abs.

M

Olá,
Tanto a sua abordagem quando a minha terá o mesmo efeito, só muda a forma.
O Spring Security irá executar essa rotina somente uma vez, que é quando o usuário se autentica no sistema, após isso ele não irá mais chamar sua rotina no DB, nem o provider no meu exemplo.

Quando você altera as pemissões do usuário isso só será refletido no próximo login.

Pelo que persebi o próximo login do usuário não é o suficiente, então o que se pode fazer é o seguinte:

1 - Crie um interceptor que irá atuar em /* menos a uri de login, ou seja todas as requisições.
2 - Para cada requisição veja no banco se houve ateração(select qualquer coisa), use SecurityContextHolder.getContext().getPrincipal() para saber quem é o usuário da requisição.
3 - Use no metodo do seu interceptor SecurityContextHolder.getContext().getAuthorities().add(new GrantedAuthorityImpl("NovaRoleQueFoiAdicionada"))
4 - Para remove segue o mesmo esquema SecurityContextHolder.getContext().getAuthorities().remove(new GrantedAuthorityImpl("RoleQueFoiRemovida"))

Espero ter ajudado.

Abraço!

O

Olá Mmaico

Achei que o Spring tivesse “nativo” esta configuração, mas tentarei implementar sua solcuação…

Muito Obrigado pela ajuda, Resolvido!

Criado 16 de novembro de 2012
Ultima resposta 19 de nov. de 2012
Respostas 4
Participantes 2