Using SQL as Session Cache in Azure - asp.net

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>

Related

Allow Concurrent Requests Per Session with Session State Provider inheriting from SessionStateStoreProviderBase

I'm using a third party CMS which is using a custom SessionStateProvider which is inheriting from System.Web.SessionState.SessionStateStoreProviderBase. System.Web.SessionState.SessionStateModule is used as SessionStateModule.
I need to allow concurrent request per session with a writable session. This can be done using the aspnet:AllowConcurrentRequestsPerSession setting when using the AsyncSessionStateModule from here. This would meet my requirement but this requires the provider to inherit from Microsoft.AspNet.SessionState.SessionStateStoreProviderAsyncBase and the provider from the third party CMS does not.
I understand this can be achieved by implementing ISessionStateModule but this seems high risk and easy to get wrong. Is there already a SessionStateModule somewhere which meet my requirements (it seems like I cannot be the first to run into this issue)?
Allows concurrent requests per session
Writable session (i.e. no SessionStateBehavior.ReadOnly to achieve concurrent request)
Supports a provider inheriting from System.Web.SessionState.SessionStateStoreProviderBase
Or am I missing something here and can this be achieved in an easier way?
I have used the Microsoft.AspNet.SessionState.SessionStateModule in a couple of different scenarios.
Microsoft.AspNet.SessionState.InProcSessionStateStoreAsync - This provider is included in the NuGet package and is a lot simpler to use as it does not require an external dependency. However, you need to ensure the user is hitting the same web-server. If you have a multiple server deployment, this requires "sticky sessions" on the load balancer.
Microsoft.Web.Redis.RedisSessionStateProvider - This provider requires 2 additional NuGet packages (Microsoft.Web.RedisSessionStateProvider and StackExchange.Redis) and an instance of Redis. While Redis is indeed very powerful, it may take some tweaking to get running smoothly. Do an internet search for "StackExchange Redis Timeout" and you will see a common problem that people face with this driver. I would only recommend this configuration in a multiple server configuration where you do not have "sticky sessions" on your load balancers.
Example web.config settings:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:AllowConcurrentRequestsPerSession" value="true" />
</appSettings>
<system.webServer>
<modules>
<remove name="Session" />
<add name="Session" type="Microsoft.AspNet.SessionState.SessionStateModuleAsync" preCondition="integratedMode" />
</modules>
</system.webServer>
<!-- Option 1: InProcSessionStateStoreAsync -->
<sessionState mode="Custom" customProvider="InProcSessionStateStoreAsync" cookieless="UseCookies">
<providers>
<add name="InProcSessionStateStoreAsync" type="Microsoft.AspNet.SessionState.InProcSessionStateStoreAsync" />
</providers>
</sessionState>
<!-- Option 2: RedisSessionStateProvider -->
<sessionState mode="Custom" customProvider="RedisSessionStateProvider" cookieless="UseCookies">
<providers>
<add name="RedisSessionStateProvider" type="Microsoft.Web.Redis.RedisSessionStateProvider" connectionString="..." />
</providers>
</sessionState>
</configuration>
As a side note, it looks like the AspNetSessionState project may already come with CosmosDB and Sql providers. YMMV - But you could try one of those if you wanted an external state server other than Redis. I ended up going with Redis mainly because it was used elsewhere in my app.

Disabling Membership in ASP.NET is not working

I am maintaining an existing asp.net website. I do not completely understand the project because another developer just handed it to me. Project is not neat. .NET version is 4 and MVC version is 4 as well. Now, I need to completely disable the membership system of the project. I found a lot of article and some changes need to be done in web.config.
I added this lines in web.config
<system.web>
<membership>
<providers>
<clear/>
</providers>
</membership>
When I run application, it throws this error.
So then I tried this instead
<membership>
<providers>
<clear />
</providers>
</membership>
<roleManager enabled="false">
<providers>
<clear />
</providers>
</roleManager>
<profile>
<providers>
<clear />
</providers>
</profile>
Then I gave me this error
How can I completely disable membership in asp.net?
Removing Membership Provider is easy. You just comment out the following 3 tags inside web.config
<system.web>
<!--<membership>...</membership>-->
<!--<roleManager enabled="true">...</roleManager>-->
<!--<profile>...</profile>-->
</system.web>
The main question is after removing, how do you plan to authenticate and authorize a user.
If you do not need authentication and allow anonymous access, you'll still need to remove [Authorize] attribute on each controller and action methods, or global filter.

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.

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>

ASP.NET Membership - Which RoleProvider to use so User.IsInRole() checks ActiveDirectory Groups?

Very simple question actually:
I currently have IIS anonymous access disabled, users are automatically logged on using their Windows login. However calling User.IsInRole("Role name") returns false. I double-checked User.Identity.Name() and the "Role name" and it should return true.
I currently have this in my Web.Config:
UPDATE
I was calling User.IsInRole("Role name") where I should call User.IsInRole("DOMAIN\Role name")
However I still like to know if the <membership> entry is needed at all?
What should I change? (and is the <membership> entry needed at all?)
<authentication mode="Windows">
<forms
name=".ADAuthCookie"
timeout="10" />
</authentication>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear/>
<add
name="ADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="XXX\specialAdUser"
connectionPassword="xx"
/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="WindowsProvider">
<providers>
<clear />
<add name="WindowsProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
If you use Windows authentication IsInRole will work with no extra configuration, as long as you remember to prefix the role with the domain, i.e. DOMAIN\groupName.
In addition you can role (pun intended) your own and use Windows auth against, for example, a SQL Role Provider, where you don't want your AD littered with custom roles for your application.
So no, you don't need the provider configuration at all.
The membership provider here isn't going to help. The ActiveDirectoryMembershipProvider seems to best(only?) fit with Forms authentication.
BlogEngine.NET has an Active Directory role provider.
Pretty sure the only thing you need in there is the roleManager group (along with the base authentication mode='windows' setting)
Out of the box, there's no role provider to use Active Directory directly. You can use the role table in the ASP.NET membership- and role-system, or you can use Authorization Manager (AzMan).
There's an article on CodeProject which shows the implementation of a role provider which works against the Active Directory - with full source code. Maybe this helps?
Marc

Resources