MVC application with ApplicationPoolIdentity on a remote IIS 8.5. Works fine with IE11 but when using Google Chrome, I get a yellow screen with System.DirectoryServices.DirectoryServicesCOMException
This is the code causing the error
protected void Session_Start()
{
// Load current AD user
UserPrincipal user = UserPrincipal.Current;
Session.Add(name: "DisplayName", value: user.DisplayName);
Session.Add(name: "AccountName", value: user.SamAccountName);
}
Also in my Web.config file I have <identity impersonate="true" /> and <validation validateIntegratedModeConfiguration="false" /> that last bit is the only way I found to make things work. But it only works in IE.
Why is it working fine in IE11 but not in Chrome? What am I doing wrong?
UPDATE #1
I can make it work when using HostingEnvironment.Impersonate() to wrap every calls to Active Directory. But it still giving me a yellow screen when I try to alter an account in AD with user.Save()
System.UnauthorizedAccessException: Access denied.
I don't have full access to Active Directory Domain but I can reset password and enable/disable accounts in my OU.
https://stackoverflow.com/a/14545336/75172
Using this class to wrap every calls to AD solved my problem.
Related
I have built MVC 5 Web application in .net 4.7.2. It runs fine in my local machine. Update and Delete commands were failing, which I have now sorted out thanks to this post: DELETE/PUT verbs result in 404 Not Found in WebAPI, only when running locally, I added this line to the web.config and all the CRUD now works:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0
However, when I publish the application to my hosting server it breaks at this line in the web.config.
When I remove the line only Create and Retrieve data works, but Update and Delete fails with the error:
Object reference not set to an instance of an object.
at this line in the Index view: Line 40: #For Each item In Model
I understand this is because the model is null/nothing at this point.
This is my delete function showing where the error starts...
Public Function Delete(ByVal id As Integer) As ActionResult
Dim Client As HttpClient = New HttpClient()
Client.BaseAddress = New Uri(myWeb & "AppMenuCRUD")
Dim APIConsumer = Client.DeleteAsync("AppMenuCRUD/" & id.ToString())
APIConsumer.Wait()
Dim Result = APIConsumer.Result << failure here: Error 404
If Result.IsSuccessStatusCode Then
Return RedirectToAction("Index")
End If
Return View("Index")
End Function
The hosted server is running Windows Server 2016, .Net 4.7.2. I have enabled read/write to the website folder.
This is my IIS Settings in the hosting server:
UPDATES:
Having looked further into this, my hosting server is now updated to .net 4.8 and everything now just fails. I am now not able to even load the index view page. It breaks at the same line 40 as above.
In IIS, my application pool is set to integrated, .net 4.0. I cannot see anything higher from the dropdown list.
In IIS, I have nothing filtered in the list of HTTP Verbs, which I believe means it should accept anything.
UPDATE 2
After the updates to .net 4.8, I am now getting a new error
Lock Violation
I have enabled everything in the IIS, including changing all the ASP Configurations from Read Only to Read/Write.
I'm fearing I may introduce vulnerabilities to the VPS...
Is there anything else I need to do to get this to work?
Sometimes you need to update manually the Web.config when you change the target framework, please double check those lines:
<system.web>
<compilation debug="true" targetFramework="4.8">
<httpRuntime targetFramework="4.8" />
...
So, this is how I finally got it to work:
I am hosted with Plesk as 'control cpanel'. Apparently, Plesk has some lock which I had to unlock here:
Plesk > Tools & Settings > Security > Prohibit the ability to override handlers
Thanks to https://support.plesk.com/hc/en-us/articles/115000287305-Site-shows-500-19-Internal-Server-Error-Config-Error-Lock-violation. I was quite surprised my host could not help with this!
In the gymnastics of enabling everything else in my VPS, I ended up enabling/installing WebDAV. This also apparently does not 'allow' Edit/Delete actions. Instead of uninstalling it, I sorted it out from the web.config like this:
<system.webserver>
...
Thanks to Web API Put Request generates an Http 405 Method Not Allowed error
I have created an MVC 5 Application with Windows Authentication,
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
I have below code to get user's Display name along with I also want to do validation,
protected void Session_Start(object sender, EventArgs e)
{
if (Context.User != null)
{
MapUserADDetails(Context.User);
}
}
private void MapUserADDetails(IPrincipal user)
{
using (HostingEnvironment.Impersonate())
using (var domain = new PrincipalContext(ContextType.Domain, "test.com"))
using (var usr = UserPrincipal.FindByIdentity(domain, user.Identity.Name))
{
if (usr == null)
{
return;
}
Session.Add("UserDisplayName", usr.DisplayName);
}
}
Now I am hosted this app to IIS with only windows authentication enabled. When I am browsing it, it's prompt for userName and Password,
Question,
Even I am entering wrong username/password or even doesn't fill anything, it's able to fetch Display Name.
How to restrict this? User/Pass must be validate against the AD. Please suggest. Thanks!
It sounds as IIS configuration issue and not the code.
To troubleshoot:
check if IE behaves differently
make sure that IIS has only Windows authentication enabled and not e.g. anonymous (see Receiving login prompt using integrated windows authentication)
make sure that the page has no other resources (e.g. images) used from other location that requires authentication (maybe that prompt is not for the page but for resources embedded into it)
check browser settings (e.g. in IE that site might need to be added into Intranet Zone, or "Automatically logon with current username and password" is not enabled)
You're not actually validating any username/password combination. UserPrincipal.FindByIdentity only checks if the user is found in AD.
To validate user credentials, you would need to check:
using (var domain = new PrincipalContext(ContextType.Domain, "test.com"))
{
bool authenticated = domain.ValidateCredentials(user.Identity.Name, password);
if (!authenticated)
{
// Do stuff
}
}
You can check MSDN for more info.
I am creating a new MVC application and trying to set up Windows authentication but when I attempt to log in it denies me.
I don't think this is related to IIS Express or my browsers as I have other MVC applications using Windows Authentication that work fine. After looking at the trade logs it appears it is attempting to connect via Anonymous Authentication which baffles me because if have this in my web.config:
<authentication mode="Windows"/>
In my project properties I have also enabled Windows Authentication and disabled Anonymous Authentication.
I'm not sure what other info to include so let me know if more is needed. Losing my mind here, please help.
UPDATE:
Closer but still not working,
Removing the following from my web config fixed my Anonymous Authentication issue:
<authorization>
</authorization>
However now in my stack trace I see the following lines that do not appear in my other working Windows authentication apps:
AspNetAppDomainEnter Data1="/LM/W3SVC/45/ROOT-1-130825677814817784" 14:36:37.272
AspNetStartHandler Data1="ASP.global_asax", Data2="Start" 14:36:37.272
AspNetPipelineEnter Data1="System.Web.Security.WindowsAuthenticationModule" 14:36:37.272
AspNetPipelineLeave Data1="System.Web.Security.WindowsAuthenticationModule"
And this is the error I get:
ModuleName ManagedPipelineHandler
Notification EXECUTE_REQUEST_HANDLER
HttpStatus 401
HttpReason Unauthorized
HttpSubStatus 0
ErrorCode The operation completed successfully.
(0x0)
ConfigExceptionInfo
Not really sure what they mean at this point but it seems like they may be related to my problem some how.
UPDATE:
My remaining issue appears to be something specific to the active directory groups I am using. Users do not seem to be in the roles I have in my FilterConfig so I am being denied access, when I remove all filter roles I get in.
RESOLVED:
For completeness I will add what fixed my authorization issue. For some reason there was a problem adding multiple Roles in my FilterConfig like so:
filters.Add(new HandleErrorAttribute());
filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = Auth.ROLE1 });
filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = Auth.ROLE2 });
filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = Auth.ROLE3 });
But when I created a roll-up group and added them all within AD to that group, then just authorized the single group like so:
filters.Add(new HandleErrorAttribute());
filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = Auth.ALL_ROLES });
It fixed my authorization issue.
You probably need to force authentication to happen, probably just add the <authorization /> tag to your <system.web> element:
<authorization>
<deny users="?" />
</authorization>
I have a project that has both an API and an Area that contains some web forms.
Recently the Token endpoint of the API started throwing CORS errors and I can't figure out why or how to fix it.
I've updated the Startup.Auth.cs file with:app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
Also tried adding config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST")); to the WebApiConfig.cs file.
Neither of these have added the 'Access-Control-Allow-Origin' header that is needed. (I do get a different error if both of these are implemented at the same time, so I know that is not the issue.)
Is there another location in the project that I need to set to allow CORS requests for an auth token?
I had to this in ApplicationOAuthProvider.cs/GrantResourceOwnerCredentials to work. The first three lines are for reference point only, "context.OwinContext" line was added to make it work.
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
**context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:24589" });**
Use above if you want to individually configure and allow CORS at different access points. If you want to allow application wide then you may modify ApplicationOAuthProvider.cs/ConfigureAuth like below. Either approach works.
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
Okay, found the problem(s).
First, my test harness was pointing at the wrong location so any changes I was making were having no effect and my break points were not being hit. My bad.
Second, the configuration that finally got me working is to have the following code:
ApplicationOAuthProvider.GrantResourceOwnerCredentials:
var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
if (allowedOrigin == null) allowedOrigin = "*";
WebApiConfig.Register:
config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST"));
I hope this helps anyone else that is struggling with CORS and Katana/OWIN middleware.
After enable CORS in WebApiConfig.cs , you should also config the web.config to also enable CORS . It's work in my application :
<system.webServer>
<!--Enbale CORS-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://yourwebsite" />
</customHeaders>
</httpProtocol>
<modules>
...
</modules>
</system.webServer>
I also struggled and spent around 5 hours, finally I got the solution.
Technology : Asp.net Framework
solution: need to install "Microsoft.Owin.Cors"
And Add the below line into "Startup.Auth.cs/ConfigureAuth()" method
app.UseCors(CorsOptions.AllowAll);
we don't want to add anything in any where, this is sufficient and it is working fine for me.
I got the answer from here: Getting token from web API2 from Angular2 leads to CORS issues or null
I am running an ASP.NET MVC 3 website on IIS. Is there a flag in web.config or something similar that can do this?
As long as you're using IIS 7 or above, it's as simple as adding it to your web.config.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Or you can add them using the IIS Management GUI, or even command line. Take a look at http://www.iis.net/configreference/system.webserver/httpprotocol/customheaders
This question originates from MVC 3, but as this problem is still relevant in ASP.NET Core, I'll let myself propose a solution for the recent versions:
public static IApplicationBuilder UseNoSniffHeaders(this IApplicationBuilder builder)
{
return builder.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
await next();
});
}
Then simply add this in Startup.cs:
app.UseNoSniffHeaders();
The beauty of this approach is that it makes it independent from your web server and deployment process. At the same time you may need to extend this solution if you want it to apply to static files as well.
In case whenever you deploy new application and its replacing the web.config file. its better to add the configuration IIS site level as below.
Click on site and select the 'HTTP response headers".
Click on 'add' on left side corner and add the name and value as below.
name: X-Content-Type-Options
value: nosniff
The nosniff response header is a way to keep a website more secure. Security researcher Scott Helme describes it like this: “It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server.