user-account-specific protection using DpapiProtectedConfigurationProvider in C# - encryption

I have to create a C# utility to encrypt and decrypt using user-account-specific protection method instead of machine based approach.
I am using DpapiProtectedConfigurationProvider as a protection provider.
Since using DpapiProtectedConfigurationProvider, by default machine based encryption is performed... how do i make a it user account based encryption?

Add the attribute useMachineProtection to your configProtectedData/providers/add element in your web.config:
<configuration>
<configProtectedData defaultProvider="SampleProvider">
<providers>
<add name="SampleProvider"
type="System.Configuration.DpapiProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
useMachineProtection="false" />
</providers>
</configProtectedData>
</configuration>

Related

Using SQL as Session Cache in Azure

I am currently looking for the best way to use session caching in an Azure Webservice. Because multiple Instances are used, standard asp.net Session state does not work.
I found some documents that this can be solved by using an external session state provider which allows using a shared cache (Redis cache) or SQL as an external provider.
But while I found a lot of documentations how to configure the Redis cache, I did not find a single example how to configure an Azure-SQL-Database for caching.
If this is still supported in Azure: Can you provide an example?
You can do this by:
<sessionState mode="SQLServer"
sqlConnectionString="Server=tcp:[serverName].database.windows.net;Database=myDataBase;User ID=[LoginForDb]#[serverName];Password=[password];Trusted_Connection=False;Encrypt=True;"
cookieless="false" timeout="20" allowCustomSqlDatabase="true" />
A nicer solution is to use table storage, because you can specify the lifetime of an object in table storage.
more info: managing-session-state-in-windows-azure-what-are-the-options
This approach may avoid needing to know how to manually create the AspNetSessionState database objects:
1) Install NuGet package https://www.nuget.org/packages/Microsoft.AspNet.Providers/2.0.0:
ASP.NET Universal Providers add provider support in ASP.NET 4 for all editions of SQL Server 2005 and later and to SQL Azure. If you use these providers to develop your application, the application will be ready for cloud environments like Azure...
It has a dependency on EntityFramework but I guess we live with that. It adds this to your web.config <system.web> section:
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
2) But for the release config you will want:
<sessionState mode="Custom" customProvider="DefaultSessionProvider" xdt:Transform="Replace">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider" connectionStringName="YourSessionConnectionStringName" />
</providers>
</sessionState>
where the xdt:Transform="Replace" is required if you use config transforms and must be removed if not.
and then the matching ConnectionString definition
<connectionStrings>
<add name="YourSessionConnectionStringName" connectionString="server=SessionServer;database=SessionDb;uid=SessionUser;password=SessionUserPassword;" />
</connectionStrings>

How can build a basic logon page using ASP.NET 4.0 using Active Directory?

I am trying to build a very basic website using ASP.NET to allow users access the private information by logging into the company Active Directory. Any help is really appreciated.
You will want to set up configuration in the web.config file to tell the ASP.Net app to use forms authentication:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" cookieless="UseCookies" />
</authentication>
Then you will need to create a membership provider that will connect to AD for authentication. Fortunately Microsoft has provided an AD membership provider out of the box, so you can use that. If you set it as the defaultProvider, ASP.Net will automatically use it for authentication.
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<add name="AspNetActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="<domainName>\administrator"
connectionPassword="password"/>
</providers>
</membership>
Finally, you will need to set up a connection string to connect to your domain controller:
<connectionStrings>
<add name="ADService" connectionString="LDAP://myCompany.com/DC=myCompany,DC=com"/>
</connectionStrings>
Look here for a good reference with more details.

Sitecore authenticate users against external membership database

I have a Sitecore site where I want to have website visitor accounts stored in an external asp.net membership database but keep Sitecore content editors/admins managed via the Sitecore interface (and hence stored in the 'Core' database).
I've read through the following forum post
http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=35305
in which the following documents are mentioned
http://sdn.sitecore.net/upload/sitecore6/62/membership_providers_sc62-a4.pdf
http://sdn.sitecore.net/upload/sitecore6/62/security_api_cookbook_sc60-62-a4.pdf
http://sdn.sitecore.net/upload/sdn5/modules/ad/low-level_sitecore_cms_security_and_custom_providers-a4.pdf
but none of these seem to provide a complete picture of what I need to do.
I've currently got the the <membership> section set up to use the 'switcher' provider (with a corresponding provider pointing to my membership DB) and the <roleManager> section also set up to use the switcher provider again with a corresponding provider pointing to said membership DB.
So far I have only succeeded in breaking the user manager in the Sitecore desktop (it throws either the exception Item has already been added. Key in dictionary: 'extranet\Anonymous' Key being added: 'extranet\Anonymous' if Sitecore has created the extranet\Anonymous account, or Object reference not set to an instance of an object. if I've deleted that user account.
As background information I'm using Sitecore 6.5 and the relevant section of my web config is as follows
<membership defaultProvider="switcher">
<providers>
<clear/>
<add name="sitecore"
type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel"
realProviderName="myProvider"
providerWildcard="%"
raiseEvents="true"/>
<add name="sql"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="core"
applicationName="sitecore"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="256"/>
<add name="switcher"
type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel"
applicationName="sitecore"
mappings="switchingProviders/membership"/>
<add name="myProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
applicationName="sitecore"
connectionStringName="myDatabase"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="10" />
</providers>
</membership>
<roleManager defaultProvider="switcher" enabled="true">
<providers>
<clear/>
<add name="sitecore"
type="Sitecore.Security.SitecoreRoleProvider, Sitecore.Kernel"
realProviderName="myProvider"
raiseEvents="true"/>
<add name="sql"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="core"
applicationName="sitecore"/>
<add name="switcher"
type="Sitecore.Security.SwitchingRoleProvider, Sitecore.Kernel"
applicationName="sitecore"
mappings="switchingProviders/roleManager"/>
<add name="myProvider"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
applicationName="sitecore"
connectionStringName="myDatabase" />
</providers>
</roleManager>
The idea you should follow in the case of custom membership/role providers is similar to what AD module lists in its setup instructions. The entire process can be split into several steps:
Adding a connection string to connectionstrings.config
Adding membership/role provider definitions to the system.web section of web.config
Activating switchers
Creating a new domain for the users/roles from custom provider
Adding domain/provider mappings
Adding a connection string
This is pretty straightforward and it seems this is what you've done already. The point is to have a connection string to the database you can then reference from the custom providers.
Adding membership/role provider definitions
Another simple step - just add a membership provider definition (myProvider in your case) under system.web/membership/providers section in web.config, and add a role provider definition under system.web/roleManager/providers section. The order is not important. At this point, you do not modify any other provider definitions in the mentioned sections.
Activating switchers
This is where it becomes complicated. First off, DON'T CHANGE the #defaultProvider attribute value. It is 'sitecore' by default and it should stay as is. Instead, find the provider called "sitecore", and change its #realProviderName attribute value from 'sql' to 'switcher'.
The provider named "switcher" is responsible for all the magic behind switching the providers and combining the results of GetAll/Find methods.
Create a new domain
You should create a new domain for the users/role you'll take from your custom DB through your custom providers. Something like this:
<domain name="myDomain" ensureAnonymousUser="false"/>
The #ensureAnonymousUser attribute being set to false means that Sitecore won't add an anonymous user to your domain, so there won't be myDomain\Anonymous. This is usually the desired behavior for the custom domains.
Adding domain/provider mappings
This is the last step to let Sitecore know which domain is served with each provider. One provider can handle multiple domains (default Sitecore SQL provider stores the users from 'sitecore' and 'extranet' domains), but not vice versa.
So, open the main web.config file and browse to the configuration/sitecore/switchingProviders section. Add something like this for memberhip subsection:
<provider providerName="myProvider" storeFullNames="false" wildcard="%"
domains="myDomain" />
and the similar thing for roleManager subsection:
<provider providerName="myProvider" storeFullNames="false" wildcard="%"
domains="myDomain" />
After this, the users from your DB will be visible as 'myDomain\user' in UserManager, the same is true for roles. The #storeFullNames='false' means that your DB stores the users/roles without domain prefixes, just the local names. Wildcard should be the default value in case your custom source is SQL (which obviously is).
That's it, and now it should work! :-) The details of the steps above are described in this article.

Using one Asp.net Membership database with multiple applications Single Sign On

I have two asp.net applications on one IIS server and I would like to use the same back end asp_security database and membership provider. I've read that all I have to do is reference the same application name in both web configs as I'm doing now, but I must be doing something wrong
In each applications web.config I have this section.
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="false"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
/>
</providers>
</membership>
When I log in from application A and browse to application B application B doesn't seem to know anything about me or my credentials from application A. Anyone have any ideas what I'm doing incorrectly?
Just for closure sake I will answer how I did achieved the goal of what my original question meant to ask for.
I had two asp.net applications on one IIS server. It was my goal to make it so when user logged onto app1 their user credentials would be available in app2. Configuring the asp.net membership provider is only one step of what I was looking for. Even if both apps were using the same back end database and provider I still wouldn't be authenticated when I hit app2. What I was looking for was a Single Sign On solution.
Once you have both apps pointing at your asp_membership database by placing the following in the system.web section of your web config
<authentication mode="Forms" />
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
applicationName="/"
/>
</providers>
</membership>
<roleManager enabled="true" />
make sure both have the same applicationname property set.
I was using IIS 6 so I configured it to autogenerate a machine key for both applications. Because both of these applications live on the same machine the key would be identical, this is the critical part to making the SSO work. After setting up IIS the following was added to my web.config
<machineKey decryptionKey="AutoGenerate" validation="SHA1" validationKey="AutoGenerate" />
That was all there was to it. Once that was done I could log into app1 and then browse to app2 and keep my security credentials.
Thanks for the push in the right direction.
If my understanding serves me correctly, the users authentication credentails are stored within the HTTP context of each application. So switching between the two applications will not automatically authenticate the user, since a new context will be created when you switch to app B.
What I believe may the correct approach would be to use the DefaultCredentials (or UseDefaultCredentials property to True) of the current user prior to switching to app B.
When you say switch what do you mean eg. open a different browser window and access app B or request a page from appB from appA?

Is it possible to use a different database name with SqlMembershipProvider

Can I specify a different database than ASPNETDB using SqlMembershipProvider? I am developing a site on a shared host, and have to restrict my data schema to a single provided database.
I was roundly scolded last time I suggested rolling my own authentication code.
Alternatively, is there some other packaged authentication system I could drop in and configure to use an arbitrary database and tables from asp.net?
You can install the ASP.Net Membership Schema to any SQL database by using the aspnet_regsql command line tool.
You can also specify any connection string you'd like for your membership provider. Simply add something like this to your membership declaration in your web.config file:
<connectionStrings>
<add name="MyConnectionString" connectionString="Database=MyDatabase;Server=xxx;User=xxx;Pwd=xxx;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<membership defaultProvider="MyProvider">
<providers>
<add connectionStringName="MyConnectionString" applicationName="/Test"
description="MyProvider" name="MyProvider" type="SqlMembershipProvider" />
</providers>
</membership>
The previous answer is largely correct, but I had a problem until I fully qualified the "Type" value to be "System.Web.Security.SqlMembershipProvider".
<membership defaultProvider="MyProvider">
<providers>
<add connectionStringName="MyProvider"
applicationName="/Test"
description="MyProvider"
name="MyProvider"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>

Resources