Pergunta

Em meu aplicativo típico, o usuário clica em um botão em uma página aspx, invoca um objeto de negócios C #, em seguida, executa um procedimento armazenado.

deve verificações de funções ser feito no topo da pilha, na parte inferior da pilha ou em todos os níveis? Parece que, se um usuário mal-intencionado pode invocar um método, ele poderia invocar qualquer, portanto, para uma segurança eficaz, seria necessário um controlo sobre todos os métodos (e isso é um monte de código extra para escrever).

Aqui está uma pilha típica chamada para ilustrar a minha pergunta:

Page_Load()
{
  if(p.IsInRole("Managers"))  //or equivalent attribute
  {
    AddAccount.Visible =true;
  }
}

AddAccount_OnClick()
{
  if(p.IsInRole("Managers"))  //or equivalent attribute
  {
    //Add the account
    Account.Add(...);  //and maybe another role check...
  }
}

-- TSQL doesn't understand .NET authorization, this call is in a 'trusted' subsystem
create proc Add_Account @user, @account_name
If @user in (Select user from role_table where role='manager')
-- Add the account
Foi útil?

Solução

Na minha opinião, você deve colocá-lo o mais próximo do número de dados possível. Quanto mais próximo estiver com os dados, o melhor que você pode garantir que ele não é possível levar algum caminho tortuoso através de sua base de código para contornar uma verificação de acesso.

Esta tese exigiria verificações de segurança a ser colocado em qualquer própria fonte de dados, se ele suporta-lo (como o seu RDBMS favorito), ou a camada de acesso a dados.

No entanto, algumas restrições de segurança têm um forte odor de lógica de negócios; por exemplo. "Se o usuário é neste papel e tentar modificar os dados que atendam a estas especificações, a operação deve ser permitida, caso contrário não". Que soa para mim como uma política, e algo que pertence tanto na camada de lógica de negócios de um mecanismo de regras separada das sortes.

eu escrevi sobre algo semelhante no contexto de WCF há algum tempo .

Outras dicas

A partir de uma perspectiva de implementação seria a melhor solução para implementar as verificações, tanto para baixo a pilha possível porque não há o menor número de funções que requerem proteção, daí o menor número de coisas a mexer-se, e todas as entradas do usuário têm de passar através da camada protegido. Se a sua fundação é protegido, você não precisa se preocupam com tudo construir sobre essa base.

Esta solução tem uma desvantagem obviouse - a interface do usuário não sabe nada sobre autenticação, autorização, verificação de dados, e todas as outras coisas. Assim, cada entrada vai para baixo da pilha, pode causar um erro, e vai até a pilha novamente para informar o usuário. Isso fará com que uma experiência de usuário desagradável porque os erros que poderiam ser facilmente detectados na interface de usuário só são detectados depois de passar os dados para os sistemas de back-end. Em conseqüência, você irá adicionar muitos cheques para o userinterface, também, a fim de dar uma melhor experiência do usuário.

Se você usar programação baseada interface, este não é um problema, porque você pode compartilhar o código de verificação entre as camadas de aplicação. Isso permite que você mais facilmente adicionar código de verificação para todas as camadas de aplicação e isso vai dar-lhe a defesa em profundidade - um bug em uma camada de aplicação pode ser pego por uma outra camada. Claro, se o próprio código de verificação é errônea e você compartilhá-lo transversalmente camadas de aplicação, o bug e Hance um erro provavelmente probagate através de todas as camadas da aplicação.

Eu colocaria as verificações de acesso papel no negócio objetos realmente executar o material potencialmente perigoso / sensível.

Adicionando a verificação de papel para o seu carregamento da página e eventos clique no botão seria estranho, IMHO. Além disso, se você estiver indo para proteger a página, proteger a página usando as directivas localização declarativas em seu web.config ... por exemplo, colocar todas as suas páginas "admin" em uma pasta separada e proteger a pasta inteira, declarativa.

Mas, você deve ter sempre os controlos dos seus métodos de objetos de negócios, como um mínimo.

Você precisa colocá-lo no nível do método. Você não pode assumir que você chegar a esse método de qualquer forma específica. Esse método pode ser chamado pelo manipulador de botão ou ele pode ser chamado no código normal como resultado de qualquer tipo de lógica. Quantas vezes você já viu algo assim chamando um botão manipulador ...

private void MyBypassingCall()
{
  if( myLogic )
  {
    AddAccount_OnClick();
  }
}

Assim, colocá-lo no Page_Load não é suficiente. Você também deve verificar se decorar o método com um PrincipalPermissionAttribute . Que reduz em um monte de código.

Este é apenas um comentário anedótica em quão importante pode ser para fazer a validação de segurança no lado do negócio. Ele não era bom o suficiente no nosso caso para ser otimista sobre baixas expectativas de pedido pirataria. Nós não têm qualquer tipo de validação em nossos objetos de negócios e se queimou de forma inesperada. Um cliente construído um script para automatizar a sua utilização do nosso site. Ele acabou seguindo os links esperados em seu script que não foram efetivamente prestados. Ele acabou corromper dados. Claro, isso é mais uma questão de estado do sistema e integridade de dados para nós, em vez de uma violação de segurança, mas suponho que ambos realmente se aplicam.

Business Objects.

Mas em tempo de construção. Que cada captura de exemplo, um papel muito específico.

Edit:. Mais sucinta desta forma

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top