Support for both Anonymous and Windows Auth in API

We are using Universal in IIS and it works fine for authentication/authorization.
The problem/ question we got now: why not have some endpoints without auth.

The problem is I can’t see a way to have both options available - am I missing something?

When I enable anon on IIS, I get everything w/o auth.
When it is disabled - I have to auth always (even if endpoint has no Role specified).

I’d love to be able to support both on the same box w/o having something in a form of two separate sites (that would also work, it just feels like a workaround). On the other hand - I’m not sure if it is even possible (as it feels like IIS just won’t allow that level of granularity).

Product: PowerShell Universal
Version: 1.5.0

I’ll have to look into this. I wouldnt have expected anon to provide access to everything without auth as I would assume the Universal server would at least be returning 401s or 403s if you try to access protected endpoints.

Version: 1.5.6

I actually can’t reproduce this and it seems to work as expected. Let me know if you can spot what I’m doing differently. Let me know if you need more information.

Server Auth Settings:

Web App Settings:

Web Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath=".\Universal.Server.exe" arguments="" forwardWindowsAuthToken="true" stdoutLogEnabled="true" stdoutLogFile=".\logs\log" hostingModel="OutOfProcess" />
  </system.webServer>
</configuration>
<!--ProjectGuid: 588ACF2E-9AE5-4DF1-BC42-BCE16A4C4EDE-->

AppSettings.json

{
  "Kestrel": {
    "Endpoints": {
      "HTTP": {
        "Url": "http://*:5000"
      }
    },
    "RedirectToHttps": "false"
  },
  "ApplicationInsights": {
    "InstrumentationKey": ""
  },
  "Logging": {
    "Path": "%PROGRAMDATA%/PowerShellUniversal/log.txt",
    "RetainedFileCountLimit": 31,
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Debug"
    }
  },
  "AllowedHosts": "*",
  "CorsHosts": "",
  "Data": {
    "RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
    "ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
    "GitRemote": "",
    "GitUserName": "",
    "GitPassword": "", 
    "ConfigurationScript": ""
  },
  "Api": {
    "Url": ""
  },
  "Authentication" : {
    "Windows": {
      "Enabled": "true"
    },
    "WSFed": {
      "Enabled": "false",
      "MetadataAddress": "",
      "Wtrealm": "",
      "CallbackPath": "/auth/signin-wsfed"
    },
    "OIDC": {
      "Enabled": "false",
      "CallbackPath": "/auth/signin-oidc",
      "ClientID": "",
      "ClientSecret": "",
      "Resource": "",
      "Authority": "",
      "ResponseType": "",
      "SaveTokens": "false"
    },
    "SessionTimeout": "25"
  },
  "Jwt": {  
    "SigningKey": "PleaseUseYourOwnSigningKeyHere",  
    "Issuer": "IronmanSoftware",
    "Audience": "PowerShellUniversal"
  },
  "UniversalDashboard": {
    "AssetsFolder": "%ProgramData%\\PowerShellUniversal\\Dashboard"
  },
  "ShowDevTools": false,
  "HideAdminConsole": false
}

Endpoints

Testing (from PS7.1)

PS C:\Users\adamr> invoke-restmethod http://localhost:82/authed
Invoke-RestMethod: Response status code does not indicate success: 401 (Unauthorized).
PS C:\Users\adamr> invoke-restmethod http://localhost:82/test
PS C:\Users\adamr> invoke-restmethod http://localhost:82/authed -UseDefaultCredentials -AllowUnencryptedAuthentication
PS C:\Users\adamr> invoke-restmethod http://localhost:82/authed -Headers @{ Authorization = "Bearer eyJhbG///" }

I cannot access the Admin Console without authenticating.

OK, I’m a bit confused now, because it looks like I have identical config (minus endpoint name/definition) but get different results…

irm https://psu.contoso.com/api/v1/endpoint/4 -UseDefaultCredentials


id             : 4
url            : /param
method         : GET
scriptBlock    :
                     Param (
                         $Foo = 'bar'
                     )
                     $Foo

authentication : True
role           : Administrator
regEx          : False
errorAction    : 0

So in theory that one should not let me in w/o credentials, right…?
But in reality I get this…:

irm https://psu.contoso.com/param?foo=somethingElse
somethingElse

Just to be sure (SID changed) here is definition of Administrator role:

irm https://psu.contoso.com/api/v1/role/Administrator -UseDefaultCredentials | % Policy

    Param (
        [Security.ClaimsPrincipal]$User
    )

    $User.HasClaim(
        'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid',
        'S-1-5-21-1111111-22222222-3333333-444444'
    )

Interesting part is that swagger API will honor requirement to have creds:

irm https://psu.contoso.com/api/v1/role/Administrator | % Policy
irm : The remote server returned an error: (401) Unauthorized.

So now I’m thinking I’m doing something wrong with endpoint configuration?