In an local Intranet environment, are we doomed to use "Classic" pipeline mode in our App Pool if we want to use Impersonate our Windows domain users, or is there a new way to declaratively "run as" them (so-to-speak)?
My goal is to use Windows Authentication for local web applications on my Intranet so users can authenticate and run apps under their active directory account (principle). Every time I try this (Using the NetworkService identity of course), I get this error:
I wrote a small app to display the current user's network username grabbed from several different places such as Page.User.Identity.Name. I also grabbed information about the domain user using a couple different methods for querying Active Directory. All this to validate the following.
I have found two primary modes for running your application using Windows Authentication, which is primarily used in an Intranet environment according to my research. Here are the minimum essential elements of the configurations:
Classic Mode
AppPool - Managed Pipeline set to Classic mode.
AppPool - Identity set to Network Service.
Authentication - Disabled: Anonymous Authentication
Authentication - Enabled: ASP.NET Impersonation
Authentication - Enabled: Windows Authentication
Providers - Disabled: Kerberos
Advanced Settings - Kernel Mode: Either
Integrated Mode
AppPool - Managed Pipeline set to Integrated mode.
AppPool - Identity set to Network Service.
Authentication - Disabled: Anonymous Authentication
Authentication - Disabled: ASP.NET Impersonation
Authentication - Enabled: Windows Authentication
Providers - Enabled: Kerberos
Advanced Settings - Kernel Mode: Disabled
Now here's the kicker!!
If you want to use Integrated mode (which is ideal as it yields much more functionality, and well, integration) you will need to have enabled Delegation. Here are a couple must-read articles to understand the basics of Delegation, and by extension Dynamic SPN Registration. Since this gets into more Kerberos and security considerations that you probably care to delve into, it might be easier to just stick with Classic mode where all you have to do is enable Impersonation and call it a day; or else cheat and disable validateIntegratedModeConfiguration.
No, but "Integrated" pipeline requires you manually impersonate the Windows Authenticated user. At least in IIS8.5, that is.
Why? Classic impersonation break .NET's async features. Specifically, it is hard to manage the WindowsIdentity of a thread when it is being used by multiple users at the same time.
How? Use a WindowsImpersonationContext e.g.
// Start with identity assigned by IIS Application Pool
var current = System.Security.Principal.WindowsIdentity.GetCurrent();
// Enable Windows Authentication in ASP.NET *and* IIS, which ensures
// User.Identity is a WindowsIdentity
WindowsIdentity clientId = (WindowsIdentity)User.Identity;
// When 'using' block ends, the thread reverts back to previous Windows identity,
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose()
using (WindowsImpersonationContext wic = clientId.Impersonate())
{
// WindowsIdentity will have changed to match clientId
current = System.Security.Principal.WindowsIdentity.GetCurrent();
}
// Back to the original identity
current = System.Security.Principal.WindowsIdentity.GetCurrent();
Problems? Sometimes you need to use delegation instead of impersonation.
Related
We are using ASP.NET Core Data Protection in combination with ASP.NET Identity with Cookie Authentication in an ASP.NET Core web application. We also send Reset-Password links using ASP.NET Core Identity which uses the data protection keys for that. We persist the data protection keys in our database using entity framework. By storing the keys in the database, we don't have any issues when swapping deployment slots in Azure.
services
.AddDataProtection()
.PersistKeysToDbContext<KeysContext>();
This all works as expected and we are running in production for several years already.
We now have a new feature, where the user can delay the sending of invitation links for new users. These generated invitation links use the ResetPassword token provider from ASP.NET Identity. We are using an Azure Function for that, where the invitation links are generated and sent in the Azure Function at a later point in time.
var token = await this.userManager.GeneratePasswordResetTokenAsync(user);
The problem now is, that the Azure Function needs to use the same data protection keys as the web application, since the generated ResetPassword tokens are later "consumed" and verified in the web application. This can be done using the ApplicationDescriminator when configuring the data protection. Every application (i.e our web application and our Azure Function) need to use the same ApplicationDescriminator:
services
.AddDataProtection(o => o.ApplicationDiscriminator = "Our-Application-Name")
.PersistKeysToDbContext<KeysContext>();
But when we now set the ApplicationDescriminator in our existing and running web application initially to "Our-Application-Name", all our already sent tokens (Invitations, Reset Password, Change Email, ...) will get invalid and also our ASP.NET Core Identity Cookie will get invalid and all users will get logged out.
Is there any way of telling the Azure Function to use the same data protection keys as the web application without changing or breaking the existing tokens in the web application?
We found a pretty hacky solution to not break the existing tokens and cookies in the web application: Instead of specifying the ApplicationDiscriminator in the web application and in the Azure Function explicitly, we specify the ApplicationDescriminator only in the Azure Function and set it to "D:\home\site\wwwroot".
This value is the default value in the web application when not specifying any value, since the default implementation in the ASP.NET Core data protection uses the HostingApplicationDiscriminator which uses the IHostEnvironment.ContentRootPath property. For an Azure deployment, this ContentRootPath is set to "D:\home\site\wwwroot" by default.
We are not very happy with this approach, since this seems like a hack, but it's still better than breaking all tokens and cookies by specifying the ApplicationDescriminator explicitly.
I am Using Sharepoint2019 On-Premise
I am looking to use separate .aspx page for authenticate users for Sharepoint2019,
I tried the Form-Based Authentication(https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server-2010/ee806890(v=office.14)) and it works for authentication but the user profiles are not getting synced from our current Active Directory, so i would like the go back to the windows authentication but instead of pop-up should i would like the .aspx
I want to Use this page for Windows Authentication :-
I Do Not Want This SIgn in pop-up
can any one please guide me to accomplish this task.
One suggestion to look at would be to use AD FS and Web Application Proxy. This solution would require you to configure Kerberos Constrained Delegation for the SharePoint Web Application. In addition, the WAP server(s) need to be joined to Active Directory. Finally, on AD FS you would set up a non-claims aware relying party.
DNS for your Web Application would be pointed at the WAP server (or load balancer routing to WAP) and users would log in there using an FBA experience but still using Windows auth on the back end.
You need an external system that can pass non-Windows auth and translate it to Windows auth. AD FS + WAP is one example of doing so. Because the back end is still Windows auth, other services that leverage Windows auth will continue to work without any changes to your farm.
See here :- https://learn.microsoft.com/en-us/answers/questions/153678/how-to-use-custom-login-page-aspx-as-link-fba-for.html
See https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-non-claims-aware-relying-party-trust on how to create a non-claims aware relying party.
For TLS setup, see https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn383662(v=ws.11).
it is quite tricky, as Microsoft Designed in that for the windows authentication, but any how if you can use the Form Base Authentication.
Here is the Link where Microsoft posted how to implement the Form Based Authentication.
Configure forms-based authentication for a claims-based Web application
With asp.net vPrev we was able to separate application pool account and access account for anonymous access ("anonymous user identity", IUSR be default). This is extremely helpful to secure the app: you may sure that no high level access will be provided for anonymous, even if application pool account has high privileges.
Is it any way to do the same for ASP.NET Core application? From my understanding of core's execution model that will not be possible, because IIS act just as a proxy. Am I right?
May be there are some ways to do the same but with an another approach? The main goal is to have ability to switch context between application pool and anonymous context. As simple example: when app starting we can read\write\do whatever with application pool account, but inside request context we will operate with anonymous user identity.
Not a fan of answering own questions, but subject is possible. You can get anonymous user context from IIS SDK:
using Microsoft.Web.Administration // from Microsoft.Web.Administration.dll, nuget microsoft.web.administration
// ....
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection anonymousAuthenticationSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication", siteName);
string userName = (string)anonymousAuthenticationSection["userName"];
string pwd = (string)anonymousAuthenticationSection["password"];
Of course this is not really secure (in have to run your app under account that have access to IIS) and you need to keep site name somewhere in config, but it works.
We have a websphere commerce application running on WAS 7. After enabling global security and application security,on accessing the application url , the browser prompts for login...only after logging in using the server admin credentials,the request is served..is this the expected behaviour of enabling security??
Yes, this is expected behavior. After enabling global and application security, access to application is enforced, if it has security configured in deployment descriptor.
Regarding admin credentials - you are probably using default file registry, with single admin user. You can change who is authorized to access application in the application details page, clicking Map user for security roles. You can specify users, groups, or special subjects like all authenticated and everyone- which would allow to access your app without login, if you really want that.
I am using Azure Mobile Apps with deployment slots, with the service provider for login being Microsoft. I have some odd behaviour, during swapping and the users relogin.
Is the performance better/different for AD? [read that it was not for GA yet?]
I am developing in a developer slot with everything specifically configured for this environment, the test and updates are working. I upload the server to staging, now utilizing the same db and settings (except microsoft authentication). The server is again verified to be working both on client and server.
I then use swap to change the staging and production slots. The production slot has the microsoft account login settings.
Upon swap the login by users are continuing indefinitely (no timeout, i.e. several minutes running without any stop) if, the referesh token call is made, as per this link:
//retrieve user info
user = new MobileServiceUser(credential.UserName);
credential.RetrievePassword();
//refresh token
user.MobileServiceAuthenticationToken = credential.Password;
JObject refreshJson = (JObject)await ((App)Application.Current).MobileService.InvokeApiAsync(
"/.auth/refresh",
System.Net.Http.HttpMethod.Get,
null);
My initial question is therefore is it possible to insert a timeout e.g. 2 seconds on the call to force the user to re-enter their credentials?
Because it seems to work if the user logs out and then back in with normal login procedure:
user = await ((App)Application.Current).MobileService.LoginAsync(provider);
credential = new PasswordCredential(provider.ToString(), user.UserId, user.MobileServiceAuthenticationToken);
vault.Add(credential);
string newToken = refreshJson["authenticationToken"].Value<string>();
Question(s)
Is it possible to insert timeout on MobileServiceClient.invokeApiAsync calls?
Is there some setting that can be set so the swap mechanism does not introduce this issue?
Is there a way to improve the login/relogin flow, the users are complaining that the login is failing often. I cannot replicate it in other instances than during the swap. Can this be because of distance to the server?
Therefore would Traffic Manager be a solution? However, I cannot see how it should be enabled if I am using microsoft login. Since a service is bound to an application name for authentication. How should the Traffic Manager be used in this respect?
Is there some setting that can be set so the swap mechanism does not introduce this issue?
Not sure if this applies to your case, but there is a known issue where certain app settings can actually cause issues with swapping. Do you have any app settings defined that end with _EXTENSION_VERSION or that start with WEBSITE_AUTH_? If so, try removing them and see if that resolves the issues you're seeing.
Is there a way to improve the login/relogin flow, the users are complaining that the login is failing often. I cannot replicate it in other instances than during the swap. Can this be because of distance to the server?
I've never head of an issue like this. Anymore details on the failure you can provide, such as a status code? One thing you can do is enable Application Logging and you should be able to get detailed information about the refresh failures.
Therefore would Traffic Manager be a solution? However, I cannot see how it should be enabled if I am using microsoft login. Since a service is bound to an application name for authentication. How should the Traffic Manager be used in this respect?
I think the way to make this work is to use a single Microsoft account application for all mobile app backends that are being load-balanced by traffic manager. The redirect URL that gets configured needs to use the common host name that is registered with Traffic Manager.
Is it possible to insert timeout on MobileServiceClient.invokeApiAsync calls?
From the API, It seems we can not set timeout in this method, refer to https://msdn.microsoft.com/en-us/library/azure/mt691682%28v=azure.10%29.aspx?f=255&MSPPError=-2147217396 for more details.