em 08-07-2024 05:27 AM
PROBLEMA INICIAL
Estava trabalhando em um último projeto de implementação do ISE, o nosso cliente queria efetuar uma forma diferente de login/cadastro ao invés da padrão, com isso de primeira mão pensamos na integração do Gov.Br, que a princípio funcionou perfeitamente, porém logo nos deparamos com um problema: a liberação dos sites na ACL da WLC para o funcionamento do portal.
Como sites de captcha ente outos eram usados para o funcionamento do portal, eles precisariam ser adicionados na ACL da WLC, o problema é que por utilizar FlexConnect, ou seja, não era suportada a adição de URLs na ACL, então precisaríamos constantemente adicionar o IP das aplicações necessárias na ACL, poderíamos criar um script para automatizar isso, mas decidimos por usar o portal guest do próprio ISE.
VALIDAÇÃO DO CPF - PROBLEMA
Como a ideia era apenas identificar quem era o usuário com base no CPF, decidimos usar o campo usuário para isso, então o usuário seria o CPF, com isso conseguiríamos ver quem realmente está acessando (claro que a pessoa poderia gerar um CPF, mas ai não seria nossa responsabilidade).
Criamos o script, porém após monitorarmos durante alguns dias, percebemos que assim que o usuário era expirado, não era possível criar um novo, pois o antigo já existia no Sponsor Portal.
Observação: para nós isso foi um problema já que queríamos manter os logs do sponsor durante 1 ano, porém se no seu caso isso não seja necessário, você poderia aborda essa utilização de CPF no usuário e colocar para o portal sponsor efetuar um purge a cada 30 dias por exemplo, e esse tempo precisa ser o mesmo que a validade da conta do usuário, no caso precisar ser 30 dias também, pois assim, quando o usuário expirar, a informação já irá sair do portal e o usuário poderá criar um novo acesso.
VALIDAÇÃO DO CPF - SOLUÇÃO
A solução ideal para satisfazer o pedido do usuário foi criar um novo campo, e nesse campo seria informado o CPF
Desvantagens: Não seria possível ver o CPF do usuário nos logs do ISE e nem diretamente pelo sponsor (é necessário clicar no usuário para visualizar o CPF).
Vantagens: Podemos guardar o log do sponsor durante 1 ano e com o nome do usuário poderíamos visualizar o CPF do mesmo.
VALIDAÇÃO DO CPF - IMPLEMENTAÇÃO
Para implementar dessa forma, é necessário ter o Sponsor e Guest Portal já configurados, isso contando com a WLC e ACLs. Com isso pronto vamos criar um campo no ISE.
Work Centers > Settings > Custom Fields
Como podemos ver na imagem, foi criado o campo chamado "CPF", agora vamos adicionar esse campo no portal.
Work Centers > Portal & Components > (Selecione o portal usado) > Registraron Form Settings > (Selecione o campo CPF e marque como obrigatório)
Agora o nosso portal já conta com esse campo, vamos adicionar o código javascript que irá efetua a formação e validação do CPF.
Portal Page Customization > Registration Form
Atenção: Para editar, selecione a linguagem que está sendo usado no portal, ou seja, se o seu portal está em PT-BR, na parte de "View In" selecione PT-BR, se isso não for feito, você vai editar um portal que não será usado, ou seja, não surtira efeito algum.
Atenção: Após colar o código certifique-se de clicar novamente no ícone que sinalizei em vermelho para fechar o campo de javascript, após o campo estar fechado, você clicar em salve, se não fizer isso o código irá ser salvo e será duplicado, o que dará erro na página posteriormente.
Abaixo está o código usado, a função para validar é a mesma usada no site da Receita Federal, já a parte de formatar o CPF foi eu quem desenvolvi, juntamente com a implementação do timeout para ser verificado constantemente.
<script>
setTimeout(function(){
$.validator.addMethod("validaCPF", function(value, element) {
value = value.replace(/\D/g, '');
var Soma;
var Resto;
Soma = 0;
if (value == "00000000000") return false;
for (i=1; i<=9; i++) Soma = Soma + parseInt(value.substring(i-1, i)) * (11 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(value.substring(9, 10)) ) return false;
Soma = 0;
for (i = 1; i <= 10; i++) Soma = Soma + parseInt(value.substring(i-1, i)) * (12 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(value.substring(10, 11) ) ) return false;
return true;
}, 'Coloque um CPF válido.');
jQuery("[name='guestUser.fieldValues.ui_cpf_text']").rules("add",{validaCPF:true});
$("[name='guestUser.fieldValues.ui_cpf_text']").on("input", function() {
if ($(this).val().length > 14) {
$(this).val($(this).val().substring(0, 14));
}
let value = $(this).val().replace(/[^0-9]/g, "").replace(/^([\d]{3})([\d]{3})?([\d]{3})?([\d]{2})?/, "$1.$2.$3-$4");
$(this).val(value);
});
}, 50);
</script>
Se você deseja alterar o campo a ser checado (como por exemplo no caso de você querer utilizar o CPF como usuário), você deve alterar onde está
'guestUser.fieldValues.ui_cpf_text'
E deverá colocar o campo desejado, no caso do usuário você deve abrir o portal e ver o nome do input:
Você deveria alterar então para:
'ui_first_name_label'
Lembre-se que o campo repete duas vezes no código, então é necessário altera toda vez em que ele repete. Outro ponto importante é que se você deseja abordar a solução de usar o CPF como usuário, para melhor visualização é necessário mudar o nome do impute de usuário para CPF.
DEMONSTRAÇÃO
No sponsor portal é necessário clica em cima do usuário:
Caso você considere o usuário como CPF, ele aparecerá dessa forma no portal sponsor:
Nos logs do ISE aparecerá o CPF em username:
CONSIDERAÇÕES FINAIS
Nos implementamos dessa forma pois o cliente gostaria de estar em conformidade com a lei que obriga a retenção de logs para caso seja necessário investigações.
Isso supre o seguinte cenário: caso alguém use a rede do cliente para efetuar um ataque, seria possível rastrear coletando informações da tabela NAT (dependendo da solução, seria necessário implementar um syslog para armazenar esses logs) para ver o IP interno, com o IP interno buscaríamos nos logs do ISE (é necessário implementar um envio automático de 7 em 7 dias dos logs - já que esse é o período máximo em que os logs são armazenados), após vincular IP com usuário, iriamos no portal sponsor (é necessário manter as informações em um período de 1 ano, ou seja, sem efetuar purge das contas nesse meio tempo) e conseguíramos ver o CPF atrelado ao usuário.
Se no ambiente do seu cliente não for usado FlexConnect, considere a implementação do Gov.Br, pois na ACL não seria necessário adicionar IP, daria para mapear as URLs necessárias, e as informações do Gov.Br poderiam ser armazenadas de uma outra forma, como por exemplo, se o Gov.Br passar pelo KeyCloack antes de chegar no ISE, poderíamos efetuar um armazenamento do lado do KeyCloack.
Enfim, são diversos cenários, com o conhecimento obtido nesse artigo você pode monta e implementar o melhor cenário para o seu cliente.
- Diego Fukayama, CCNA, DCPT, eWPTXv2, CNSS.
Excelente conteúdo @Diego Fukayama !
Conteúdo incrível, @Diego Fukayama! Parabéns!
Muito bom Conteúdo, @Diego Fukayama Parabéns meu nobre!
Baita Diego! Parabéns
Muito bom, @Diego Fukayama! Parabens!
Ótimo artigo @Diego Fukayama
A versão do post inicial não estava funcionando no meu teste em 3.2 p7. Adaptei o código e abaixo temos funcionando:
<script>
setTimeout(function() {
// Add CPF validation method using jQuery validator
$.validator.addMethod("validaCPF", function(value, element) {
value = value.replace(/\D/g, ''); // Remove non-numeric characters
var Soma;
var Resto;
Soma = 0;
if (value == "00000000000") return false; // Check for invalid CPF (e.g., 000.000.000-00)
if (value == "11111111111") return false; // Check for invalid CPF (e.g., 111.111.111-11)
if (value == "22222222222") return false; // Check for invalid CPF (e.g., 222.222.222-22)
if (value == "33333333333") return false; // Check for invalid CPF (e.g., 333.333.333-33)
if (value == "44444444444") return false; // Check for invalid CPF (e.g., 444.444.444-44)
if (value == "55555555555") return false; // Check for invalid CPF (e.g., 555.555.555-55)
if (value == "66666666666") return false; // Check for invalid CPF (e.g., 666.666.666-66)
if (value == "77777777777") return false; // Check for invalid CPF (e.g., 777.777.777-77)
if (value == "88888888888") return false; // Check for invalid CPF (e.g., 888.888.888-88)
if (value == "99999999999") return false; // Check for invalid CPF (e.g., 999.999.999-99)
// CPF first check digit
for (i = 1; i <= 9; i++) Soma = Soma + parseInt(value.substring(i - 1, i)) * (11 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(value.substring(9, 10))) return false;
// CPF second check digit
Soma = 0;
for (i = 1; i <= 10; i++) Soma = Soma + parseInt(value.substring(i - 1, i)) * (12 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(value.substring(10, 11))) return false;
return true;
}, 'Coloque um CPF válido.');
// Apply CPF validation to the field
jQuery("#guestUser\\.fieldValues\\.ui_cpf_text").rules("add", { validaCPF: true });
// CPF Formatting: Apply mask as XXX.XXX.XXX-XX
$("#guestUser\\.fieldValues\\.ui_cpf_text").on("input", function() {
if ($(this).val().length > 14) {
$(this).val($(this).val().substring(0, 14)); // Limit length to 14 (XXX.XXX.XXX-XX format)
}
let value = $(this).val().replace(/[^0-9]/g, "")
.replace(/^([\d]{3})([\d]{3})?([\d]{3})?([\d]{2})?/, "$1.$2.$3-$4");
$(this).val(value); // Apply formatted value
});
// Phone Validation: Phone number format (XXX) XXXXX-XXXX
jQuery("#guestUser\\.fieldValues\\.ui_phone_number").attr("placeholder", "(XX)9XXXX-XXXX");
jQuery("#guestUser\\.fieldValues\\.ui_phone_number").attr("type", "number");
setTimeout(function(){
cisco.ise.validation.setPhoneRegex (/^\(?(\d{2})\)?(\d{5})[- ]?(\d{4})$/);
cisco.ise.validation.setPhoneNumberMessage("Informe seu numero de celular (XX)9XXXX-XXXX");
});
// Form submission handler
$("#selfRegForm").validate({
rules: {
"#guestUser\\.fieldValues\\.ui_cpf_text": {
required: true,
validaCPF: true
},
"#guestUser\\.fieldValues\\.ui_phone_number": {
required: true,
minlength: 14, // Minimum length for phone number (formatted as (XX) XXXXX-XXXX)
maxlength: 14
}
},
messages: {
"#guestUser\\.fieldValues\\.ui_cpf_text": {
required: "Por favor, CPF requerido. Insira seu CPF.",
validaCPF: "Por favor, CPF inválido. insira um CPF válido."
},
"#guestUser\\.fieldValues\\.ui_phone_number": {
required: "Por favor, telefone requerido. Insira um número de telefone.",
minlength: "Por favor, insira um número de caracteres maior de telefone para ser válido.",
maxlength: "Por favor, insira um número de caracteres menor de telefone para ser válido"
}
},
// If validation fails, prevent form submission
submitHandler: function(form) {
form.submit(); // Submit the form if all fields are valid
}
});
}, 50);
</script>
Realmente ficou muito bem estruturado!
Regards,
Josinfo
Encontre respostas, faça perguntas e conecte-se com nossa comunidade de especialistas da Cisco de todo o mundo.
Estamos felizes por você estar aqui! Participe de conversas e conecte-se com sua comunidade.
Navegue pelos links rápidos da Comunidade e usufrua de um conteúdo personalizado e em seu idioma nativo: