PowerShell / Polaris

A cross-platform, minimalist web framework for PowerShell
https://powershell.github.io/Polaris/
MIT License
512 stars 114 forks source link

Adding Authentication Support #150

Closed jeremymcgee73 closed 5 years ago

jeremymcgee73 commented 6 years ago

Sorry for the amount of Commits. I am still getting used to using Git! I added support for Basic Auth using the HTTPListener methods. I would suggest using HTTPS when using Basic Auth, because the password is clear text in the request.

This should work on Linux. I do not expect this to be merged yet. I would like to work on tests firsts. I will also work on trying this in Linux. I did some testing on PowerShell core on Windows.

jeremymcgee73 commented 6 years ago

I gave it a shot to switch to using [System.Net.AuthenticationSchemes] as the type for the auth parameter. I believe we should stick to using ValidateSet instead of passing in the correct type. This allows us to limit what auth schema's we allow. I also ran into an issue where the assembly wasn't loaded in the ISE to create the object before calling Start-Polaris. I think it may also help with future proofing, for when we switch to Kestrel. @tylerl0706 Thoughts?

awickham10 commented 6 years ago

Does this do any sort of validation on allowed users?

jeremymcgee73 commented 6 years ago

@awickham10 There is a IsInRole method on the User object in the request. But, I don't believe it works with basic auth. Let me try adding negotiate auth and see if IsInRole works. The worst case, is you could add middleware that checks membership with Get-ADGroupMember.

jeremymcgee73 commented 6 years ago

@awickham10 I added NTLM and Negotiate auth. Here is an example below on how to check if the user is in a group. Can you test this when you have some time?


New-PolarisGetRoute -Path "/helloworld" -Scriptblock {
    $IsInGroup = $request.User.IsInRole('DOMAIN\AD group')
    $Response.Send($IsInGroup)
}

Start-Polaris -Port 443 -Https -Auth Negotiate
TylerLeonhardt commented 6 years ago

Just out of curiosity, have you been testing on Linux at all?

This could just mean throwing an "Unsupported platform" exception.

jeremymcgee73 commented 6 years ago

I have not. I am starting to do research to figure out which Auth Schemes are supported on Linux. It seems searching corefx issues are the only way to find this information. I have tested on core on Windows, and that does work as expected.

Tiberriver256 commented 6 years ago

@TylerLeonhardt - I know... I've been thinking about the tests on this as well but I think we can actually get away with testing most of the functionality since (in theory) it's tested up-stream in httplistener.

We should however write tests for any functionality we lay on top of it. i.e. if we write code that shows an error when IntegratedWindowsAuthentication is attempted on a Linux machine we should write a test to verify that error is thrown, but since we're leveraging the httplistener library implementation of basic, ntlm, negotiate, kerberos (integrated windows authentication), etc. instead of writing our own middleware implementation I don't think re-testing their code produces a whole lot of value up front.

If we did want to write our own tests though I think we could probably just try to replicate the authentication tests from the httplistener class itself:

https://github.com/dotnet/corefx/blob/master/src/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs

jeremymcgee73 commented 6 years ago

I did some work on this tonight. It will now throw errors if you you try to use anything other than Basic or Anonymous auth on Linux. I did test Basic Auth on linux and it does work. I tested the other auth providers on PowerShell for Windows and Core. I can work on tests to make sure the expected errors are thrown.

If we are able to create users in the test scripts, we can probably test most auth providers.

jeremymcgee73 commented 5 years ago

@Tiberriver256 I added tests validating that errors were thrown, when applicable. Do you think more tests should be added? There was a random one that failed on Linux. But, I think it was a false positive. Is there a way to fire off AppVeyor again?

Tiberriver256 commented 5 years ago

@TylerLeonhardt - Did you want to see any other tests added on this?