Search code examples
javaspringaop

Spring @Before changing every user login


I have a @Aspect class, that execute a @Before method and intercept all queries with some Id from the login of user. But the problem is: every time a user make login, the Id from @Before method change for all logged users, it just must to change the current user.

The simple process: when a user make login, the @Aspect class gets his id to intercept all queries. But this id is changing for every logged user. Maybe should be a problem with session, I really do not know.

The aspect class:

@Aspect
@Component
@Transactional(propagation = Propagation.REQUIRED)
public class TenancyAspect {

    @Autowired
    private EntityManager manager;

    @Autowired
    private AppUserDetailsService appUserDetailsService;

    @Before("execution(* com.tc.tcqualidade.repository.*.*(..)) "
            +"&& !execution(* com.tc.tcqualidade.repository.UsuarioRepository.porEmailEStatus(..))"
            +"&& !execution(* com.tc.tcqualidade.repository.UsuarioRepository.permissoes(..))")
    public void definirTenant() {
        String tenantid = appUserDetailsService.getTenantId();

        if (tenantid != null) {
            manager.unwrap(Session.class).enableFilter("tenant").setParameter("id", tenantid);
        }

    }

}

The login class:

@Service
public class AppUserDetailsService implements UserDetailsService {

    private String tenantId = null;

    @Autowired
    private UsuarioRepository usuarioRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Optional<Usuario> usuarioOptional = usuarioRepository.porEmailEStatus(email);
        Usuario usuario = usuarioOptional.orElseThrow(() -> new UsernameNotFoundException("Usuário e/ou senha incorretos"));

        tenantId = usuario.getEmpresa().getId().toString();

        return new UsuarioSistema(usuario, getPermissoes(usuario));
    }

    private Collection<? extends GrantedAuthority> getPermissoes(Usuario usuario) {
        Set<SimpleGrantedAuthority> authorities = new HashSet<>();

        List<String> permissoes = usuarioRepository.permissoes(usuario);
        permissoes.forEach(p -> authorities.add(new SimpleGrantedAuthority(p.toUpperCase())));

        return authorities;
    }

    public String getTenantId(){
        return tenantId;
    }

}

Solution

  • I've seen this same behaviour when using @Autowired. Spring will not create a new instance on each access unless you tell it do so, so the object is shared across all accesses. A user logging in, caused all logged in users to change to that user's id. You might need to make one of your services session scoped:

    @Service
    @Scope(value="session", proxyMode= ScopedProxyMode.TARGET_CLASS)