Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC5 : Turn off Windows Authentication on a single page

My website (ASP.NET MVC5 with Entity Framework) use the Windows Authentication system. It is very useful and enable me to get more information about the user by searching an Active Directory. I can automatically fill form fields with information like e-mail, ...

Web.config:

[...]
<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>
[...]

I have a Powershell script (that do another job) which must access to one page of the site to send some information. I need to provide this access to the script, without any authentication (turn off Windows Authentication only for this Action/Page). I used at first the attribute AllowAnonymous, that had no effect.

Action in my controller:

[AllowAnonymous]
    public ActionResult ReceiveData(string scriptVersion, string content)
    {
        try
        {
            if (scriptVersion != null && content != null)
            {
                HttpUtility.UrlDecode(content);                    
                Xxxxx.UpdatexxxxxxServer(content); // I just replaced the name of my project
                return new HttpStatusCodeResult(200, "OK");
            }

            return new HttpStatusCodeResult(403, "You're not allowed to do this.");
        }
        catch(Exception e)
        {
            return new HttpStatusCodeResult(400, "Unable to execute this request on the DB. Detailed error: " + e.Message);
        }            

    }

Powershell script (only for info, no need to understand it for this question purpose):

$url = "http://localhost:3349/Xxxxxx/ReceiveData"
$parameters = "scriptVersion=2&content=$([System.Web.HttpUtility]::UrlEncode($(Get-Content "$scriptFile")))"

$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open('POST', $url, $false)
$http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
$http_request.setRequestHeader("Content-length", $parameters.length)
$http_request.setRequestHeader("Connection", "close")
$http_request.send($parameters)

When my script reach the send method, He ask me for credential, and I don't want to provide each time credentials (And i don't want to put my credentials in the script). That is why I expected to disable the Windows Authentication on this Action.

I've done some research, trying to find any working solution. I saw this subject : MVC 5.0 [AllowAnonymous] and the new IAuthenticationFilter AllowAnonymous attribute seems to not working in MVC5 with the addition of new filter. That's why I have tried to add a custom filter:

public class CustomAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter 
{        
    public void OnAuthentication(AuthenticationContext filterContext)
    {

    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        var user = filterContext.HttpContext.User;
        if (user == null || !user.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}

I added it on the FilterConfig and put the CustomAuthenticationAttribute on my Action ReceiveData. No better result... All the action are going in this filter but I can't disable Windows Authentication on my Action.

My modified action:

[AllowAnonymous]
[CustomAuthenticationAttribute]
public ActionResult ReceiveData(string scriptVersion, string content) {
    [...]
}

I'm not an expert and it would be cool if you can help me find the solution and understand it. Thanks in advance and sorry for the english mistakes, this is not my native language.

like image 635
Martin Avatar asked Mar 14 '23 08:03

Martin


1 Answers

That's how I did it:

  1. Run notepad as admin
  2. Open %WINDIR%\System32\inetsrv\config\applicationHost.config
  3. Save it as %WINDIR%\System32\inetsrv\config\applicationHost.config.bak for backup purposes
  4. Find following string:

    <section name="anonymousAuthentication" overrideModeDefault="Deny" />
    
  5. Replace Deny with Allow
  6. Save file as %WINDIR%\System32\inetsrv\config\applicationHost.config
  7. Go to your web application folder
  8. Open web.config
  9. Find <configuration> section
  10. Paste this inside your <configuration> section:

    <!-- ANONYMOUS ACCESS FOR POWERSHELL SCRIPT -->
    <location path="ReceiveData.aspx">
        <system.webServer>
            <security>
                <authentication>
                    <anonymousAuthentication enabled="true" />
                </authentication>
            </security>
        </system.webServer>
    </location>
    
  11. Save file
  12. Recycle app pool, to be 100% sure that IIS re-reads web.config

Update:

I have modifed the .config file. Is it only available for local IIS?

Yes, this approach uses IIS to configure anonymous authentication. I can't help with the code, because I'm not a developer. Perhaps you should wait for someone with actual C# knowledge to answer.

Do I must to perform this change on my "non-development" environment?

Yes, you have to change global seetings in %WINDIR%\System32\inetsrv\config\applicationHost.config to be able to override anonymousAuthentication in per-application web.config.

About the code: I work with MVC, so i don't have any .aspx pages. I changed the path to MyController/ReceiveDate, is it correct?

Probably. <location path=> has to be "relative virtual path", which is "root relative virtual path to the script or path for the current request"

I don't have "recycle the app pool" because I really don't know how to do this : I work with the IIS Visual Studio.

Recycling app pool is not needed, IIS should recycle it itself, if it detects web.config changes. But rarely it not happens or happens with noticable delay.

After testing my PowerShell script with your solution, I get an error 500.19.

What's HRESULT code of the error? Maybe you mistyped something in web.config? See this article for details: "HTTP Error 500.19" error when you open an IIS 7.0 Webpage

like image 102
beatcracker Avatar answered Mar 23 '23 10:03

beatcracker