Pergunta

Eu estou lutando com a construção de um provedor de associação personalizado que me permite ter a necessidade esquema de segurança I.

Eu tenho meu próprio IPrincipal, IIdentity e MembershipProvider. Eu tenho a multa de autenticação de trabalho. O problema que eu estou correndo em agora é a autorização.

O problema que tenho com o regime de autorização é inherintly no comportamento IsInRole do IPrincipal. Este comportamento está intimamente ligado a vários recursos do ASP.NET Webforms, minha principal preocupação é a autorização mapa do site, porque eu gostaria de usá-lo se eu puder.

Assim que você pode tradicionalmente tem um mapa do site assim:

<siteMap xmlns="blahblah">
    <siteMapNode url="PersonView.aspx" 
        title="View Person" 
        description="View the details of a person" 
        roles="ViewerRole" />
</siteMap>

Aqui, qualquer um que tenta ir para a página PersonView.aspx serão obrigados a ter o ViewerRole. Este é o lugar onde meu problema surge. Eu não quero ter a minha autorização ligada a função de um usuário. Em vez disso, eu quero que a autorização para ser amarrado ao comportamento que eu estou realizando e deixar algo subjacente nos bastidores cuidar da autorização.

Então, o que eu realmente quero é algo parecido com isso em vez disso:

<siteMap xmlns="blahblah">
    <siteMapNode url="PersonView.aspx" 
        title="View Person" 
        description="View the details of a person" 
        roles="Person|View" />
</siteMap>

Esta deve ser interpretado como alguém tentando ir para a página PersonView.aspx deve ter Ver direitos para o Person objeto de negócios.

Eu já tenho um objeto Autorizador que tem uma assinatura assim:

public static bool Authorize(Type type, Access access, IUser user)

Que terá, por exemplo, o tipo de pessoa, o acesso Vista (enum), e ao usuário verificar se contra. Agora, eu tenho o código dentro do Autorizar descoberto.

O meu problema é, como faço para começar a partir de IsInRole do IPrincipal ao meu Autorizar? Eu tentei coisas diferentes, mas nenhum deles parece funcionar. Eu realmente não gosto da abordagem corda mágica, mas parece que eu estou preso com ele. Se houvesse uma maneira de construí-lo de uma forma fortemente tipado Eu definitivamente preferem que, em vez. Existe uma maneira melhor de fazer isso que não estou pensando?

Foi útil?

Solução

Outra maneira Eu já vi esse tipo de coisa feita é quando initalizing ao usuário armazenar todos os direitos e objetos como uma papéis no Principal. Dependendo do número de objetos que você tem isso pode ser outra opção. Essencialmente, você iria se livrar da chamada Authorizer.Authorize, e armazenar

  • Vista | Person
  • Editar | Person
  • add | Peron

Como três papéis diferentes. Eu já vi isso usado em um sistema que tinha uma hierarquia de recursos para que você possa ter Feature A -> Feature B, C ou D, por exemplo, onde BC e D só pode existir se tiver A. Este poderia então ser papéis como :

  • A
  • A | B ou A | C ou A | D

Então agora o seu código pode verificar se A ou se você precisa verificar subfeature você pode verificar A | B.

Sugestão

Para fazer o seu impl ainda melhor em sua página carregar E se você fez:

if (Context.User.IsInRole(
       PermissionFactory.CreateToken(AuthorizationType.Person,Access.View)))  
{        
  //I have view rights, do some stuff    
}

Agora você tem escondido o fato de que esta é uma seqüência completamente.

Outras dicas

Eu descobri uma maneira bastante limpa para resolver o meu problema. O que fiz foi mudar minha assinatura Autorizar a aceitar uma enumeração em vez do tipo e uso que no IsInRole para determinar permissão.

Então, eu tenho:

public static bool Authorize(AuthorizationType type, Access access, IUser user)

e então eu usá-lo em IsInRole assim:

public bool IsInRole(string role)
{
    var typeAndAccess = role.Split('|');
    var authType = 
        (AuthorizationType)Enum.Parse(
            typeof(AuthorizationType), typeAndAccess[0]);
    var access = (Access)Enum.Parse(typeof(Access), typeAndAccess[1]);

    return Authorizer.Authorize(
        authType, access, Context.User.Identity as IUser);
}

Isso me permite usar a abordagem corda mágica quando eu absolutamente necessário (como em um mapa do site), mas também permite-me uma abordagem mais fortemente digitado quando eu estou usando-o por meio de programação como:

void Page_Load(...)
{
    if (Context.User.IsInRole(AuthorizationType.Person + '|' + Access.View)
    {
        //I have view rights, do some stuff
    }   
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top