GithubHelp home page GithubHelp logo

quasoft / websspi Goto Github PK

View Code? Open in Web Editor NEW
30.0 4.0 7.0 99 KB

HTTP auth middleware for Go that uses Kerberos/NTLM SPNEGO with SSPI for single sign-on authentication of HTTP requests in Windows environments

License: MIT License

Go 100.00%
golang go http auth middleware kerberos spnego sspi sso single-sign-on

websspi's Introduction

websspi

GoDoc Build Status Coverage Status Go Report Card

websspi is an HTTP middleware for Golang that uses Kerberos/NTLM for single sign-on (SSO) authentication of browser based clients in a Windows environment.

It performs authentication of HTTP requests without the need to create or use keytab files.

The middleware implements the scheme defined by RFC4559 (SPNEGO-based HTTP Authentication in Microsoft Windows) to exchange security tokens via HTTP headers and uses SSPI (Security Support Provider Interface) to authenticate HTTP requests.

How to use

The examples directory contains a simple web server that demonstrates how to use the package. Before trying it, you need to prepare your environment:

  1. Create a separate user account in active directory, under which the web server process will be running (eg. user under the domain.local domain)

  2. Create a service principal name for the host with class HTTP:

    • Start Command prompt or PowerShell as domain administrator

    • Run the command below, replacing host.domain.local with the fully qualified domain name of the server where the web application will be running, and domain\user with the name of the account created in step 1.:

      setspn -A HTTP/host.domain.local domain\user
      
  3. Start the web server app under the account created in step 1.

  4. If you are using Chrome, Edge or Internet Explorer, add the URL of the web app to the Local intranet sites (Internet Options -> Security -> Local intranet -> Sites)

  5. Start Chrome, Edge or Internet Explorer and navigate to the URL of the web app (eg. http://host.domain.local:9000)

  6. The web app should greet you with the name of your AD account without asking you to login. In case it doesn't, make sure that:

    • You are not running the web browser on the same server where the web app is running. You should be running the web browser on a domain joined computer (client) that is different from the server. If you do run the web browser at the same server SSPI package will fallback to NTLM protocol and Kerberos will not be used.
    • There is only one HTTP/... SPN for the host
    • The SPN contains only the hostname, without the port
    • You have added the URL of the web app to the Local intranet zone
    • The clocks of the server and client should not differ with more than 5 minutes
    • Integrated Windows Authentication should be enabled in Internet Explorer (under Advanced settings)

Security requirements

  • SPNEGO over HTTP provides no facilities for protection of the authroization data contained in HTTP headers (the Authorization and WWW-Authenticate headers), which means that the web server MUST enforce use of HTTPS to provide confidentiality for the data in those headers!

websspi's People

Contributors

quasoft avatar varbin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

websspi's Issues

Get all groups for a user

While looking at the code, I noticed that groups for a user are retrieved using the NetUserGetGroups function. From testing I've done, I've noticed that this only retrieves groups the user is directly assigned, and it will not retrieve groups the user is indirectly assigned, such as groups containing groups containing the user. Also, NetUserGetGroups requires providing the server name of a DC in order to get the groups of a domain user.

With some experimenting, I found that the groups can be obtained from the CtxtHandle. By using QueryContextAttributes passing the SECPKG_ATTR_ACCESS_TOKEN attribute (value 18), an SecPkgContext_AccessToken value is returned, which contains an access token, which can be passed to GetTokenInformation using the TokenGroups class, which results in TOKEN_GROUPS value.

The TOKEN_GROUPS value will contain an array of group SIDs and attributes assigned, and, by filtering the groups to only include those containing an attribute bit flag SE_GROUP_ENABLED, and using LookupAccountSid, a list of group names can be achieved.

Given this amount of work, I would have wanted to instead include a pull request. However, this is the first time I'm writing any Go code, I wasn't really able to make any progress except by using the helper functions defined in golang.org/x/sys/windows, and I was only able to make it work by removing tests (rather than augmenting and modifying the tests to work with the updated code). If you would still like to see the changes I made to help clarify the above description of work, I can make that available.

Authentication fails on multipart/form-data POSTs above ~2.5Mb

Every time I try to upload a file larger than ~2.5Mb to my webapp, websspi logs the following error message and stops execution:

2023/06/05 11:31:51 Authenticating request to ...
2023/06/05 11:31:51 Authentication failed with error: could not get auth data: the Authorization header is not provided

With smaller files, it works prefectly.

Resolve linked token.

It might be desirable adding a configuration parameter to do group lookup over the TokenLinkedToken. This contains the "elevated" token, if the UAC filtered the direct token.

Using the default, filtered token (as introduced by this PR) should remain the default, as this is the default for Windows applications (e.g. when using Powershell Remoting). At the same time, if developers want to e.g. allow login depending on administrative rights, using the linked token might be useful.

Shall I open a new PR for:

  1. Improved documentation, describing why groups might be missing and differences between previous lookup.
  2. A configuration parameter for toggling between using the regular and the linked token.

Oh, and I could do #4 at the same time.

Get only username

Hi, quasoft!
It's not an issue, but a question.
It is possible to get only the user name and do not perform auth? I do not have access to domain controller and can't add user to AD.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.