I have a client server application. The client is an asp.net c# site and the server is simply a command line application in c#. I plan on using .NET remoting to access and expose information that is on the server application and preset it to the user viewing the client.
The server application has user objects that i want to use for authentication with the asp.net login controls etc.
I implemented created a custom class "MyMembershipProvider" which implements MembershipProvider but i'm getting very confused now. What do i do next?
i know i need to update the Web.config with a "membership" node but all the examples i've seen have a reference to a connection string, mine does not need a connection string as it will not be using a database etc.
OK so i figured it out.
I don't need a connection string or anything. All i had to do was put:
<membership defaultProvider="Name of the class that you created that implements the MembershipProvider class">
<providers>
<clear/>
<add
name="Name of the class that you created that implements the MembershipProvider clas"
type="fully qualified name of the class that you created that implements the MembershipProvider class" />
</providers>
</membership>
I finally realized that the element above has to be inside the < system.web > element and that fixed it, thanks for your help.
Hope you find this article useful.
http://learn.iis.net/page.aspx/528/how-to-use-the-sample-read-only-xml-membership-and-role-providers-with-iis-70/
You need to better understand why web.config needs a certain configuration, as those database based providers have a reason to use connection strings in web.config. Then you know how to configure your provider (without a connection string as yours does not use database).
Related
I am currently working on a Sitecore project where the same sitecore webapplication would point to Sitecore databases based on witch IIS website name the webapplication is running under.
Let’s say the IIS webapplication is called www.company1.com, then the database names would be: www.company1.com.master, www.company1.com.web in \App_Config\ConnectionStrings.config.
I have tried to modify the connection string on Application_Start(), but that is not the best solution (possible but slow and ugly, first request dropped etc.).
Another approach is to use config file transformations, but that is not an options based on the number of web sites.
Is it possible to modify Sitecore.Context, somewhere in Application_Start – so Sitecore.Context.Database would work as expected?
You could setup multiple connection strings entries and then reference it in the node in your web.config.
<connectionStrings>
<add name="core" connectionString="[connection_string]" />
<add name="master" connectionString="[connection_string]" />
<add name="web" connectionString="[connection_string]" />
<add name="web1" connectionString="[connection_string]" />
<add name="web2" connectionString="[connection_string]" />
</connectionStrings>
<sites>
<site name="website1" database="web1" hostName="www.company1.com" (...) />
<site name="website2" database="web2" hostName="www.company2.com" (...) />
</sites>
Would that work for you?
I don't think there is. But you would not want to change the actual name of the connection string, you would want to change the value produced by it. Changing the standard Sitecore connection string names ("master", "core" and "web") would require a lot of related changes in web.config and related config files. On top of that you would probably end up in trouble, as there are modules and code out there still - doing specific Factory.GetDatabase("master") API calls - even if they shouldn't.
I've never attempted what you're asking for here in a Sitecore solution, but I expect it should be possible to create your own ConnectionStringProvider, as described in http://msdn.microsoft.com/en-us/library/vstudio/ms254494(v=vs.100).aspx
The provider would need to return proper results for "master", "core" and so on - any databases you would normally have defined in your solution - and then a dynamic connection string based on the pattern you describe; considering the IIS application name or whatever you need.
In my web.config file I have two SQL Server connection strings, one for local and one for live:
<connectionStrings>
<remove name="LocalSqlServer" />
<add name="LocalSqlServer" connectionString="[removed]" providerName="System.Data.SqlClient"/>
<add name="LiveSqlServer" connectionString="[removed]" providerName="System.Data.SqlClient"/>
</connectionStrings>
I then have a "utils" singleton class which basically sets the connection string depending if I'm running the site on "localhost" or on my live server:
if (Environment.MachineName.ToUpper() == MyOwnConfig.GetAppSettingsValue(ConfigKeys.localhost).ToUpper()) {
this.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString();
//MembershipProvider provider = Membership.Providers["LocalAspNetMemberSqlProvider"];
//RoleProvider role = Roles.Providers["LocalAspNetMemberSqlProvider"];
}
else {
this.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["LiveSqlServer"].ToString();
//MembershipProvider provider = Membership.Providers["LiveAspNetMemberSqlProvider"];
//RoleProvider role = Roles.Providers["LiveAspNetMemberSqlProvider"];
}
My Database class then simply uses the connectionString property of my utils class. All this works fine so when I place the site locally I can then simply upload it to live without making changes to the connection strings etc in the config file and it starts using my live database.
Now I'm currently implementing "membership" into my site and for ajax for use some webmethods I'm storing the providerUserKey in a text field of the current logged in user. my web method then checks that this key is authenticated. e.g.
ajaxCreds.ajaxID1 = ((MembershipUser)Membership.GetUser()).ProviderUserKey.ToString();
QUESTION:
the question I have is How do I know if this membership is from the LIVE database or my LOCAL database. As you can see from the web config I've added in the membership/provider lines (commented out) but I don't know how to use them with the above membership.getUser() command.
Alternative... Is this a good way to go? or is it simpler to edit the web.config file when I upload to live?
Many thanks
Most people don't do it this way though I applaud you for figuring all this out. Typically, people use the deployment manager or some other build system to have a different web.config value on the server verses local.
Here is a link on changing in deployment: How do I use Web.Config transform on my connection strings?
I would suggest you to read this article:
http://blogs.msdn.com/b/schlepticons/archive/2010/07/22/modifying-asp-net-providers-at-runtime.aspx
It will show you, that also others were trying to do the similar. And this is how to succeed. Solution (if adjusted) could be similar to your needs.
put all the providers into your web.config
On App_Start adjust which will be the default (based on the Environment)
Membership API will be available as you need for Provider Key
No need to search for Provider by Name
NOTE: you have to tweak the void Application_Start(object sender, EventArgs e) implementation but the idea is there
NOTE2: What you are trying to do is definitely not exception. Configuration based on environment is pretty smart! What must be achieved is standard API usage, e.g. calls via Manager pattern
System.Web.Security.Membership
System.Web.Security.Roles
and not calls to the providers by name.
I am new to MVC 3 and went through lots of cool tutorials. Loving the design pattern and enjoying the productivity boost.
One of the problems I am now having is that I was using the built in database to handle the login that is behind many of the basic MVC apps in most tutorials. I now need to change to access the login details of a live production system this but cant find where to do it.
I initially taught is would be as simple as changing the connection string, but the production database is totally different than the made up example.
It is not obvious to me where the model / controller is getting the data from. For example, where does the model / controller retreive the user name or compair the password. If I knew this then I could alter my solution to point to the correct database / tables / fields.
Also, my real database is modelled in EF and is in a separate project within the same solution. So I have MyProject.Data and MyProject.Web and eventually will have MyProject.Test ect.
Any help here would be greatly appreicated. Thanks in advance.
EDIT 1: The real database also has a login table with user name and password fields, just like the MVC simple login db. However the database is obviously not part of the system like in the sample projects. Instead it is sitting on the server waiting to be accessed.
My problem is that I dont know where to go to make the changes needed. I was thinking it would be the connection string but this is not working. Even the errors I get just point me back to the connection string as opposed to giving me a line of code to find.
The framework pulls the connection string that is named the same as the DbContext derived class by default. So look for a connection string that is the same as this class. Having said that this connection string has absolutely nothing to do with the default forms implementation as that pulls from connection string that is identified in the membership section of the web.config. This should look something like this:
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
in there you see the connectionStringName identified. You can of course simply change this, but most likely if you already have an existing database, this will most likely not be structured correctly.
The comment by Henk is most likely right in that you will want to create your own membership provider (simply create a class and inherit from MembershipProvider and implement CreateUser, GetUser, ValidateUser, and ApplicationName (or so I think)). You need to make sure to register this provider in place of the AspNetMembershipProvider. Once you do that you should see breakpoints be hit on your provider and simply implement as you need it for your database/AD/...
I have a class that needs to check the Authentication Mode from a web.config.
Ex:
<authentication mode="Forms" />
or
<authentication mode="Windows" />
Now, I know this can be done pretty easily with the following code:
AuthenticationSection sec = ConfigurationManager.GetSection("system.web/authentication");
if (sec.Mode == "Windows")
{ ... }
My problem is, this class/project is being referenced in my Web project, as well as a WinForms project. The WinForms project is requiring .NET 4.0 Client Profile Framework (we don't want to require the full .NET 4 Framework, if possible). If I'm not mistaken, the Client Profile does not contain System.Web.dll.
Is there a way that this value can be checked without referencing System.Web (and preferably without manually parsing the config file)?
I've tried:
object authSection = ConfigurationManager.GetSection("system.web/authentication");
if (authSection.ToString() == "Windows")
{ ... }
However the ToString() simply returns the string "System.Web.Configuration.AuthenticationSection".
Thank you!
I have used the above code to get the authentication mode. I just done few changes in your code. Please find here.
AuthenticationSection authSection = (AuthenticationSection)ConfigurationManager.GetSection("system.web/authentication");
if (authSection.Mode.ToString() == "Windows")
Hey if your talking about a web config in the same project try using the following method.
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel)
Or you could use one of the other similar methods in the ConfigurationManager members. I can't test it for you at the moment but I'm pretty sure they should work. Because essentially they don't care what kind of conf file it is as long as there is one as since the inherited type of the web.config is a config, you should be able to access it just like any other and query for the particular field you need.
ConfigurationManager
Where in your code do you need to make a decision on this? If the user is authenticated at that point you could use IIdentity.AuthenticationType and process accordingly. For Forms this will always return Forms, for a Windows identity it typically NTLM, although it can be Negotiate or Kerberos.
I am trying to develop a website with C# ASP.net MVC. It's my first time using Visual Studio, C# and ASP.net so I have lots to learn but so far so good.
So far... I started a C# ASP.net MVC project and added a database by going to the Database Explorer and clicking "add connection". I then did some standard CRUD controllers and views.
I am at the stage where I want to implement User authentication. I'm a bit confused here. I am trying to make a custom Membership Provider. So I added it to my web.config file with the correct connection string etc.
When I run the project and go to register I get an error. "Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'."
From searching, I see lots of people have this problem and they always reference their hosting. People say this (http://weblogs.asp.net/scottgu/archive/2005/08/25/423703.aspx) is their solution but when I try pick a database I get an error. Not even sure of my server name.
So at this point I am wondering, did I set up the database right?
EDIT
Adding in a few pics to show exactly what I am doing. This is the aspnet_regsql.exe:
This is the provider with connection string, taken from an example on one of the links given.
This is my customized provider with connection string pointing to the last image.
This is a screen cap when I run the project and go to the default project Account register action:
and finally, this is the error screen when I submit
EDIT
Another update..
I sorted something out but I am not sure if it is correct. I am now getting an error when the page loads: "Invalid object name 'dbo.Tag'"
In order to solve this problem the only thing you need to do is create an application services DB. You can achieve this by running the following command from your Visual Studio Command Prompt
aspnet_regsql
Anyways it seems that your "custom provider" isn't using a custom structure for your DB, which might be the reason why you weren't expecting this error.
If you are using the default implementation, you can access to the user administration using ASP .NET Configuration, located on your project menu in visual studio.
The default implementation uses the following conn string keyword
LocalSqlServer
The are many ways of implementing the membership provider. My guess is that probably this conn string is not pointing to your aspnet services db, you could do something like this to specify a custom location for this db
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnetdb.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" />
I made a blog post regarding this topic: How to use MembershipRole Provider and when to use custom implementations
It's hard to figure out anything from your post.
but when I try pick a database I get
an error.
You can check your server name in Surface area configuration or Sql Server Configuration Manager. If you installed Visual Studio it's probably YOUR_MACHINE_NAME\SQLEXPRESS. You can connect to it using Windows Authentication. You could also write localhost,1433 instead, but that would require enabling TCP/IP first(it's disabled by default) and setting the port number first(which in most cases is already set).