Recentemente estive envolvido em um projeto simples mas um tanto quanto interessante. Estávamos fazendo a configuração de um servidor Web e todas as aplicações ASP.NET 2.0 que ali seriam hospedadas devem utilizar uma mesma base de dados para as funcionalidades de Membership, Roles e Profile.
A questão é que as aplicações podem ter um arquivo Web.Config e customizar essas configurações em cada uma delas. Só que isso não seria permitido. A solução foi até mais simples do que imaginava e, me forçou a olhar para alguns atributos que nunca prestei a devida atenção até então. Todos os elementos que são colocados nos arquivos de configuração herdam (diretamente ou indiretamente) da classe ConfigurationElement. Essa classe possui 5 principais propriedades (ou atributos):
-
lockAllAttributesExcept: Informa que todos os atributos de um elemento serão bloqueados, com exceção dos atributos que estão contidos nesta lista.
-
lockAllElementsExcept: Informa que todos os elementos de um elemento “pai” serão bloqueados, com exceção dos elementos que estão contidos nesta lista.
-
lockAttributes: Bloqueia apenas os atributos contidos nesta lista.
-
lockElements: Bloqueia apenas os elementos contidos nesta lista.
-
lockItem: Bloqueia o item como um tudo e, conseqüentemente, todos os seus “filhos”.
Para que fosse possível isso, editamos o arquivo Machine.Config e lá colocamos todas as configurações necessárias para que as aplicações pudessem herdar as configurações estipuladas para Membership, Roles e Profile e não ter direito de sobrescreve-las. Com isso, o arquivo Machine.Config fica definido como:
<?xml version=”1.0″>
<configuration>
<connectionStrings>
<add
name=”LocalSqlServer”
connectionString=”CONN_STRING”
providerName=”System.Data.SqlClient”
lockItem=”true” />
</connectionStrings>
<system.web>
<membership defaultProvider=”AspNetSqlMembershipProvider” lockAttributes=”defaultProvider”>
<providers lockElements=”clear”>
<add
name=”AspNetSqlMembershipProvider”
type=”System.Web.Security.SqlMembershipProvider, System.Web”
connectionStringName=”LocalSqlServer”
enablePasswordRetrieval=”false”
enablePasswordReset=”true”
requiresQuestionAndAnswer=”true”
applicationName=”/”
requiresUniqueEmail=”false”
passwordFormat=”Hashed”
maxInvalidPasswordAttempts=”5″
minRequiredPasswordLength=”7″
minRequiredNonalphanumericCharacters=”1″
passwordAttemptWindow=”10″
passwordStrengthRegularExpression=””
lockAttributes=”connectionStringName;enablePasswordRetrieval;passwordFormat” />
</providers>
</membership>
</system.web>
</configuration>
Obviamente que algumas aplicações devem customizar algum desses atributos e, justamente por isso, que nem todos os elementos/atributos foram bloqueados. Por exemplo, se desejar customizar o nome da aplicação no arquivo Web.Config de cada uma das aplicações, então podemos fazer:
<?xml version=”1.0″?>
<configuration>
<system.web>
<membership userIsOnlineTimeWindow=”10″>
<providers>
<remove name=”AspNetSqlMembershipProvider”/>
<add
name=”AspNetSqlMembershipProvider”
type=”System.Web.Security.SqlMembershipProvider, System.Web”
applicationName=”Teste” />
</providers>
</membership>
</system.web>
</configuration>
Nada impede do desenvolvedor poder adicionar novos providers de memberships, roles e profiles mas, ele não poderá habilitá-lo, já que o atributo defaultProvider está bloqueado a nível superior. Um outro detalhe importante é podemos remover o provider especificado no arquivo Machine.Config através do elemento remove mas, sendo assim, ele não poderá utilizar as funcionalidades de Membership definidas para o servidor.