ASP.net Identity can't login - asp.net

I'm using Asp.net Identity and I've deployed my web role to Azure, and changed my connection string in Web.config so it looks like this:
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=SERVERNAME,1433;Database=DATABASE;User ID=USER;Password=PASSWORD;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
I haven't changed default Account controller, but when I try to Login nothing nothing happens except that URL changes to "/Account/Login?ReturnUrl=%2FRoutines" which should happen if user successfully logged in (no errors are shown)
Why is this happening ? (and how can I fix it)
EDIT
Here is code which configures ASP.net Identity
public class DatabaseContext : IdentityDbContext<User>
{
public DatabaseContext()
: base("DefaultConnection")
{
Configuration.LazyLoadingEnabled = true;
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Users");
modelBuilder.Entity<User>()
.ToTable("Users");
var usermapping = new UserMapping();
usermapping.MapUser(modelBuilder);
}
I've noticed that now even when I'm using LocalDb I can't Log in, and I don't know why is this because, I haven't changed my code, only changes that I made to the project is Added Azure web service, and Asp.net web Api 2 project (and when I've tested locally I didn't run my web api project), before this everything worked fine.

Are you sure your connection is really used when you deploy (in Web.config.release)?
In case you are, try testing the website locally (with the Azure SQL connection string) and stepping through the code for POST version of Login. There you should be able to see, what exactly is going on. You will probably need to enable access to SQL from your IP address, which is easy to do - just go to Azure Portal, click on your SQL database and down below select Manage, which will automatically ask you for your IP address access permission.

I don't know what I exactly happened, but I've fetched older version of solution from TFS and that helped (eve though code was same)

Related

Fatal Communication Error with the Windows Process Activation Service

I have a .NET WebAPI app working locally on my dev machine's IIS, but if I deploy it on a server, there I get the error
HTTP Error 503. The service is unavailable.
whenever I try to access the API. At the same moment, the AppPool stops (yes, it has started correctly and runs correctly until I make an API call) and I get the error in event viewer:
A process serving application pool 'MyNewTestAppPool' suffered a fatal communication error with the Windows Process Activation Service.
The controller I call is a really complicated one:
public class ExampleController : ApiController
{
[HttpGet]
public bool GetTrue()
{
return true;
}
}
so this cannot be an issue with a stack overflow caused by endless loop inside my code. I fear that it is an endless loop inside the authentication and authorization chain.
The main change to another app that deployed correctly on the same server is that this app should have most controllers require authentication against local AD, with a single controller that doesn't - while the other apps either always require authentication, or never.
To achieve this hybrid mode, I did the following:
in Web.config, I added <authentication mode="Windows" />
in IIS, I enabled both Anonymous Authentication and Windows Authentication
in Global.asax.cs, I added the AuthorizeAttribute to all controllers: GlobalConfiguration.Configuration.Filters.Add(new System.Web.Http.AuthorizeAttribute());
the single function that should be accessible without authentication has got the [AllowAnonymous] attribute set.
Not sure what's happening there, does someone know what happens or how to debug this?
Ensure \IIS_IUSRS (IIS 7.x) has read access to the app folder. Ensure the app pool identity you are using is in the IIS_IUSRS group (ex. IIS APPPOOL\DefaultAppPool)

How to set machineKey on Azure Website

I'm running an Azure Website. Whenever I deploy, everyone gets logged out because the machineKey changes.
I specified the machineKey in the web.config but this didn't solve the issue. I believe this is because Azure automatically overwrites the machineKey [1].
I've found a couple of similar questions here but the answers link to dead links.
So, what's the solution? Surely there's a way to keep users logged in regardless of deployments on Azure.
Try to reset the machine-key configuration section upon Application_Start:
protected void Application_Start()
{
// ...
var mksType = typeof(MachineKeySection);
var mksSection = ConfigurationManager.GetSection("system.web/machineKey") as MachineKeySection;
var resetMethod = mksType.GetMethod("Reset", BindingFlags.NonPublic | BindingFlags.Instance);
var newConfig = new MachineKeySection();
newConfig.ApplicationName = mksSection.ApplicationName;
newConfig.CompatibilityMode = mksSection.CompatibilityMode;
newConfig.DataProtectorType = mksSection.DataProtectorType;
newConfig.Validation = mksSection.Validation;
newConfig.ValidationKey = ConfigurationManager.AppSettings["MK_ValidationKey"];
newConfig.DecryptionKey = ConfigurationManager.AppSettings["MK_DecryptionKey"];
newConfig.Decryption = ConfigurationManager.AppSettings["MK_Decryption"]; // default: AES
newConfig.ValidationAlgorithm = ConfigurationManager.AppSettings["MK_ValidationAlgorithm"]; // default: SHA1
resetMethod.Invoke(mksSection, new object[] { newConfig });
}
The above assumes you set the appropriate values in the <appSettings> section:
<appSettings>
<add key="MK_ValidationKey" value="...08EB13BEC0E42B3F0F06B2C319B..." />
<add key="MK_DecryptionKey" value="...BB72FCE34A7B913DFC414E86BB5..." />
<add key="MK_Decryption" value="AES" />
<add key="MK_ValidationAlgorithm" value="SHA1" />
</appSettings>
But you can load your actual values from any configuration source you like.
If Azure is rewriting your machineKey, you can't do much about it, as it is part of their infrastructure. However, there are other methods.
Override FormsAuthentication
This should not be difficult as you can easily look up for source code of FormsAuthentication and create your own logic and replace MachineKey with your own key stored in web.config or in your database.
Custom Authentication Filter
The simplest way would be to create a filter and check, verify, encrypt decrypt cookies in your filter. You need to do this on OnAuthorization method and create new instance of IPrincipal and set IsAuthenticated to true if descryption was successful.
OAuth
Enable OAuth and create OAuthProvider. However you will need to host OAuthProvider on server that is in your control as that will need machineKey working.
Enable Third Party OAuth, if you enable OAuth with Google, Facebook etc, it will be easy as user will be redirected to OAuth provider and they will continue to login automatically and a new session will be established.
I had the same issue and in my case I was using the webdeploy to Azure wizard in VS13. I thought I was going crazy as I would set the machinekey in the web.config and then it would be changed on the deployed web.config to autogenerate. It is something in the webdeploy script/settings. My solution was to open the live azure site from within VS13 using the Server Explorer and then editing the web.config and saving changes. This preserved my settings with my supplied keys and all works fine.

ConnectionFailureException thrown in XP when using SMO with Windows Authentication

I'm trying to use SMO in a ASP.NET web project to get a list of the server's Databases. The method I'm using seems to work fine on a Windows 7 machine, but the second I install it on an XP machine, I get a ConnectionFailureException. The code I'm using to establish the connection is:
ServerConnection connection = new ServerConnection(serverName);
Server serverConnection = new Server(connection);
string[] databases;
try
{
databases = new string[serverConnection.Databases.Count];
}
catch { databases = new string[0]; }
On the Windows 7 machine, I get an empty array of length however many databases there are, which I then add the database names to in a foreach loop, but in Windows XP, it fails in the try block, and I get:
ConnectionFailureException: Failed to connect to server localhost.
-> Login failed for user 'ComputerName\\ASPNET'.
I'm guessing this is some kind of permissions problem with the ASPNET user, but I can't seem to find anything that's solved the problem. In IIS, I unselected Anonymous Access and selected Integrated Windows Authentication, and set
<authentication mode="Windows" />
in the web.config.
Anyone have any suggestions/sage-like advice to share?
Do you want web application to impersonate a user to connect to SQL?
When you use SQL Management Studio you are connecting to SQL directly; when you are doing it from web application then you are calling it and IIS calls yours SQL. Now the question is which login IIS uses when accessing SQL - whether it impersonates you under W7 and does not doing it under XP?
For sure XP does not impersonates you and uses 'ComputerName\ASPNET' as you shown in the error message. IIS6 ASPNET impersonation setting are described here and IIS7 here. By default in both IISes impersonation is turned off but I am not sure what is your current configuration on W7. Maybe you should turn it on under IIS6?

ELMAH: Can you set it up to email errors only remotely?

While debugging my solution locally, I would like to not receive ELMAH error emails. I'd only like to receive them when the application is hosted on a remote machine. Is this possible?
I faced the same problem and rejected the idea of having different web.configs for local and remote as that just doesn't play nicely with source control (but see comments below).
Instead, I added this to a Global.asax file in each site which uses Elmah:
void ErrorMail_Mailing(object sender, ErrorMailEventArgs e)
{
e.OnErrorMailing(); // Prevent local machine errors from being mailed to the rest of the team
}
OnErrorMailing() is an extension method declared in our web library as follows:
/// <summary>
/// Prevent local machine errors from being mailed to the rest of the team. Feel free to add your own machine names/case blocks here
/// </summary>
public static void OnErrorMailing(this ErrorMailEventArgs e)
{
switch (e.Error.HostName.ToLower())
{
case "mymachinename":
e.Mail.To.Clear();
e.Mail.To.Add("MYEMAILADDRESS");
break;
}
}
Of course if you have only one site which uses Elmah or you don't mind code duplication you can put that code straight into global.asax too.
I've no doubt there are more elegant solutions but this works for me. Only I receive the exceptions from my local machine and production exceptions go to the email address configured in web.config.
I'm pretty sure you can do this. Just filter outgoing error emails. Of course use some setting to indicate that it's hosted remotely.
Or just have two different web.configs and make sure "dev one" has emaling turned off.
You can have emails go to a pickup folder on your local machine instead of the SMTP server by modifying the web.config file
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\" />
</smtp>
</mailSettings>
</system.net>
Or you can put this in your Machine.config settings on your dev box so you don't have to keep touching the web.config file.
I found a solution which is to use config transforms with VS 2010. I removed the <errorMail /> tag from my base web.config then added it to my Web.Qa.Config and Web.Release.Config with transform tags. When I publish, it allows the remote machines to send out the emails while they are suppressed locally.

asp.net authentication - use credentials from web.config - problem

I have a simple problem which is giving me headaches for a couple of days.
I've created very simple application with login control. I keep user data in web.config file:
<authentication mode="Forms">
<forms name=".RzeskoLoginCookie">
<credentials passwordFormat="Clear">
<user name="test" password="test"/>
</credentials>
</forms>
</authentication>
I will deploy this simple website to IIS on computer on which I do not want to use SQL Server.
My login button event looks like this:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Now the problem:
When I am running a website on VS2008 built in webserver, everything works fine (I can log in). When I copy my website to IIS I am constantly getting this annoying error (after I click Login button):
Failed to generate a user instance of
SQL Server due to failure in
retrieving the user's local
application data path. Please make
sure the user has a local user profile
on the computer. The connection will
be closed.
I also observed that in my App_Data folder some weird files are being created.
To sum up. What I want to achieve is to use user credentials from web.config file, without using sql server.
I'd appreciate any help
Kind Regards
PK
From the MSDN page for Login control:
*
The Login control uses a membership
provider to obtain user credentials.
Unless you specify otherwise, the
Login control uses the default
membership provider defined in the
Web.config file. To specify a
different provider, set the
MembershipProvider property to one of
the membership provider names defined
in your application's Web.config file.
For more information, see Membership
Providers.
*
The default Membership provider is the AspNetSqlProvider which uses a SQL Server database as its user store.
If you want to provide a custom authentication routine, you can either write your own custom Membership provider or handle the OnAuthenticate method of the Login control to provide your own authentication logic.
If you notice in your code, you have the method declaration for handling the <asp:Login> control's LoggingIn event:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
This control interfaces with the ASP.NET Membership provider which is probably why it is looking for a connection string.
So rather than using the <asp:Login> control, simply use a button and handle the Click event so that there is no use of Membership:
<asp:Button id="LoginButton" Text="Login" OnClick="Login_OnClick" runat="server" />
Code behind (notice the different signature of the method):
public void Login_OnClick(object sender, EventArgs args)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Ok, thanks everybody for pointing out the solution.
I finally managed to avoid that error by creating my own authentication event (associated with the login control).

Resources