Pergunta

Vamos dizer que eu tenho um ASP.Net MVC App e este aplicativo (UI) referências a camada de lógica de negócios (BLL) e as referências BLL meu Data Access Layer (DAL).

Estou utilizando uma associação personalizado e provedor de função para autorização.

Eu estou tentando determinar o que camadas precisa referenciar o meu provedor de associação.

Em MVC você pode executar verificações de autorização da seguinte maneira:

[Authorize(Roles = "SomeRoleName")]
public ActionResult Index()
{
//do something
}

E no meu BLL I pode querer verificar para ver se um usuário está em um papel também:

public static bool IsRoleEditor(User user, Role userRole)
  {
   bool retValue = false;

   if (user.Application.AppID == UserRole.Application.AppID)
   {
        if (Roles.IsUserInRole("ModifyRoles"))
        {
           retValue = true;
        }


    return retValue;
   }

Eu teria de referência e instanciar as classes de adesão em ambas as camadas se eu fizer isso. É este o caminho correto para o arquiteto de um aplicativo como este? Parece que um monte de redundância.

Uma vez que eu tenho um BLL faço para evitar o uso de "[Authorize (Roles = 'SomeRoleName')]" atributos e, em vez chamar uma função BLL de dentro do código MVC para verificar se o usuário está em um papel? Se eu fizer isso o MVC ainda precisa de uma referência para o provedor de associação para autenticação e como uma maneira de aproveitar o login e outros controles ASP, certo?

Am I longe de base e indo na direção errada?

Foi útil?

Solução

Na minha opinião, este é um ponto fraco do projeto Membership / Role.

A maneira que eu iria contornar isso, por exemplo, para ter autorização baseada em função em ambos os níveis de interface do usuário e BLL em um aplicativo de n-tier distribuído, seria expor um serviço na camada BLL que expõe as partes relevantes (GetRolesForUser etc) e é implementado chamando o RoleProvider no servidor.

Em seguida, implementar um RoleProvider personalizada no cliente que é implementada por chamar o serviço exposto pelo BLL.

Desta forma, a camada de interface do usuário e BLL camadas ambos compartilham a mesma RoleProvider. A camada de interface do usuário pode usar o conhecimento das funções do usuário atual para melhorar a interface do usuário (por exemplo, esconder / desativar controles de interface do usuário correspondentes a recursos não autorizadas), eo BLL pode garantir que os usuários não podem executar lógica de negócios para as quais não estão autorizadas.

Outras dicas

Excelente pergunta, eu me perguntava a mesma coisa hoje. Um dos idéia que eu tinha (mas eu realmente não estou certo se é a melhor maneira de ir) é a utilização de uma interface (ex: IRoleProvider). Que você pode passar para o seu BLL para testar o seu acesso

public static bool IsRoleEditor(User user, IRoleProvider rp)
{
     return (rp.IsUserInRole(user,"ModifyRoles"));
}

Com isso, você ainda verificar o seu acesso em sua BLL, você pode usar um mock em seus testes de unidade para verificar sua lógica e você só precisa criar uma classe (ou implementar isso em uma classe BaseController) em seu site MVC que irá implementar IRoleProvider e fazer a verificação adequada usando autorização ASP.NET API.

Esperamos que isto ajude.

Obtenha seu objeto de usuário para implementar a interface IPrincipal e jogar que cerca as camadas. Em seguida, você ainda pode usar o construída em atributo [autorizarão].

Athough escrito ao longo de 3 anos e cerca de castelo, este artigo pode ajudar. Ele começa a se metendo as coisas a meio caminho para baixo IPrincipal.

HTHS
Charles

Por que não passar os papéis em seu BLL para que você não tem qualquer dependência Membership. Ou usar uma interface como MartinB sugeriu.

O que acontece no futuro, quando o seu titular jogo (s) decidir ir com uma forma diferente de autenticação e você já não trabalho com um Papel objeto?

Exemplo:

IsRoleEditor(User user, string[] roles)
{
  return roles.Contains("ModifyRoles");
}

Você não faltando o ponto de MVC. MVC divide a naturaly em camadas. Modelo (DAL), controlador (BLL), Vista (Apresentação). Estes podem ir em diferentes projetos, se você gosta, mas como o controlador tem toda a lógica do negócio - você só precisa acessar o RoleProvider há

.

Em seguida, aplicar padrões tais como o repositório, padrão etc para dividir a mais se você quiser.

Davy

Para chamar o controlador MVC 'UI' é maneira fora da marca .. O 'C' no MVC é parte do seu BLL, mesmo se ele faz referência classes que você chamaria a BLL. No entanto, esse não é o ponto de sua pergunta.

Eu acho que eu poderia resolver este problema fazendo a pergunta, "há uma exigência real para 100% separação de seu aplicativo 'UI' e seu 'BLL'?". Se ambos os componentes compartilham uma dependência sobre os prestadores de membro / papel, então que seja assim e começar a trabalhar.

No caso em que você desconecte seu BLL e conectar uma nova, talvez ter uma dependência compartilhada em um provedor de .NET é algo que você pode viver com. Você sabe que é provavelmente ok e sua aplicação só pode não desmoronar.

Eu acho resposta de Joe acima faz muito sentido embora ...

Eu acho que você está fazendo é bom.

A autorização e autenticação deve viver dentro de uma camada de serviços, que, talvez, é passado para seus controladores.

Se o controlador define o Principal e Identidade e você, em seguida, usar isso no controlador através do uso do MVC atributos então ele soa como uma boa idéia.

Seria bom para esconder o seu provedor de MVC Membership atrás de uma interface, de que maneira você pode trocá-lo para um provedor de WinForms Membership (por exemplo) e seria capaz de teste de unidade seus controladores.

acesso

Papel normalmente não devem estar na BLL. O acesso é uma responsabilidade interface do usuário.

Com o que disse, a alavancagem da interface IPrinciple como os cartazes acima afirmaram. Você tem acesso a IPrinciple no nível da linha.

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