Skip to content

kbase/auth2

Repository files navigation

KBase authentication server

This repo contains the second iteration of the KBase authentication server.

Build status (master): Build Status codecov

Current endpoints

UI

UI endpoints are not versioned and not necessarily stable - behavior may change as needed to support the auth UI.

Note that the HTML UI supplied in this repo is a minimal implementation for the purposes of testing. In many cases a manual refresh of the page will be required to see changes. Further, once a checkbox is manually checked or unchecked that state will not change, even with a refresh - to see changes reset the form.

/
General server information including git commit, version, and server time.

/admin
Global admin tasks - force reset all passwords, revoke all tokens, view a token, search for users.

/admin/customroles
View, add, and delete custom roles.

/admin/config
View and edit the server configuration.

/admin/localaccount
Create a local account.

/admin/user/<user name>
View user, disable user, reset password, force password reset, and modify user roles.

/admin/user/<user name>/tokens
View and revoke tokens for a specific user.

/customroles
View custom roles. This page is publicly viewable to any user with a valid token.

/link
Link accounts.

/login
Login to a provider based account. Stores a cookie with a token.

/localaccount/login
Login to a local account. Stores a cookie with a token.

/localaccount/reset
Reset the password for a local account.

/logout
Logs the user out.
Removes the user's token from the database as well as any temporary link tokens associated with the user. Removes the login, temporary login, and temporary link cookies except if JSON output is requested, in which case it is expected that the UI manages the login token (but not the temporary tokens).

/me
User page. Update name and email address, remove roles.

/tokens
List, create, and revoke tokens.

API

API endpoints are versioned and behavior should not change in a backwards incompatible manner without a change in version.

All API calls require a valid token in the Authorization header except legacy API endpoints, which continue to use their original protocol. All endpoints produce JSON data unless otherwise noted.

Tokens are opaque strings - no particular structure should be assumed, and token string contents may change without notice.

GET /api/V2/me
See the current user's profile.

PUT /api/V2/me
Update the current user's email address and display name. Takes JSON encoded data with the keys display and email.

GET /api/V2/users/?list=<comma separated user names>
Validate a set of user names and get the users' display names. Returns a map of username -> display name. Any usernames that do not correspond to accounts will not be included in the map.

GET /api/V2/users/search/<prefix>/?fields=<comma separated fields>
Find users based on a prefix of the username or any parts of the display name, where parts are delimited by whitespace. By default the search occurs on all fields; setting the fields query parameter can restrict the search fields and thus possibly speed up the search. Current field names are username and displayname; any other field names are ignored. Returns a map of username -> display name. At most 10,000 names are returned.

GET /api/V2/token
Introspect a token.

POST /api/V2/token
Create an agent token. Takes JSON encoded data with the keys name for a required token name string and customcontext for an optional map of user-supplied creation context to be saved with the token, and returned when the token is queried.

GET /api/v2/admin/anonids?list=<comma separated anonymous user IDs>
Translate anonymous user IDs to user names. Admin (and exactly Admin) permission is required. At most 10000 IDs are allowed, but the URL size limit effectively limits the count to less than that. Disabled users are not returned; IDs not found in the database are omitted from the map.

RETURNS:

{
  <anonymous ID 1>: <user name 1>,
  ...
  <anonymous ID N>: <user name N>
}

Legacy

Endpoints (mostly) identical to the original Globus and KBase auth endpoints are provided for backwards compatibility.

POST /api/legacy/KBase/Sessions/Login
The legacy KBase API.

GET /api/legacy/globus
The legacy globus API. Endpoints are /goauth/token and /users.

Test Mode

Test mode allows integration of the auth service into test harnesses for dependent services and applications by providing endpoints for creating test users, tokens, and roles on the fly. A subset of the API above is supported (see below).

To enable test mode, add the following line to the service deploy.cfg file:

test-mode-enabled=true

Test mode should never be enabled for production services.

All test mode data is stored in separate collections from the standard data in the service data stores, and is automatically deleted one hour after creation. Test mode user accounts have no passwords and no linked identities and so logging into test mode accounts is impossible, although tokens can be created arbitrarily. Note that test mode user accounts are more or less arbitrarily specified as local accounts in the API.

Test mode data is only accessible via endpoints under the /testmode root endpoint.

Standard endpoints

These endpoints mimic the behavior of the standard API endpoints above, but only interact with test mode data.

GET /testmode

GET /testmode/api/V2/me

GET /testmode/api/V2/token

GET /testmode/api/V2/users

POST /testmode/api/legacy/KBase/Sessions/Login

GET /testmode/api/legacy/globus

Data manipulation endpoints

These endpoints allow a test harness to create and modify test mode users, tokens, and roles. No authentication is required.

POST /testmode/api/V2/testmodeonly/user
Create a user. Takes JSON encoded data with the keys user for the user name and display for the user's display name.

GET /testmode/api/V2/testmodeonly/user/<username>
Get a user's data.

POST /testmode/api/V2/testmodeonly/token
Create a token. The user to which the token is assigned must exist. Takes JSON encoded data with the keys user for the user name, name for an optional token name, and type for the token type. type is one of Login, Agent, Dev, or Serv.

POST /testmode/api/V2/testmodeonly/customroles
Create a custom role. Takes JSON encoded data with the keys id for the role id and desc for the role description. Posting a role with an existing ID overwrites the description of the role.

GET /testmode/api/V2/testmodeonly/customroles
Get the list of extant custom roles.

PUT /testmode/api/V2/testmodeonly/userroles
Set a user's roles, overwriting any current roles. Takes JSON encoded data with the keys user for the user name of the user to modify, roles for a list of built-in roles to grant to the user, and customroles for a list of custom role ids to grant to the user. Allowed roles are DevToken, ServToken, Admin, and CreateAdmin. Note that these roles don't grant any actual privileges in test mode. Omitting roles and customroles removes all roles from the user.

DELETE /testmode/api/V2/testmodeonly/clear
Removes all test mode data from the system.

Administration

Notes

  • It is expected that this server always runs behind a reverse proxy (such as nginx) that enforces https / TLS and as such the auth server is configured to allow cookies to be set over insecure connections.

    • If the reverse proxy rewrites paths for the auth server, cookie path rewriting must be enabled for the /login and /link paths. Nginx example:

      location /auth/ {
      	proxy_pass http://localhost:20002/;
      	proxy_cookie_path /login /auth/login;
      	proxy_cookie_path /link /auth/link;
      	
      	# If using alternate environments (see below)
      	add_header X-AUTH-ENV "environment_name";
      }
      
  • Get Globus creds here

    • Required scopes are:
      • urn:globus:auth:scope:auth.globus.org:view_identities
      • email
  • Get Google OAuth2 creds here

  • Get OrcID creds here

    • Note that only the public API has been tested with the auth server.

Migration notes

0.6.0
  • In version 0.6.0, the canonicalization algorithm for user display names changed and the database needs to be updated.
    • See the --recanonicalize-display-names option for the manage_auth script (See the administration section below). This can be run while the server is live after updating to version 0.6.0.
    • Once the names have been recanonicalized, the --remove-recanonicalization-flag can be used to remove flags set on database objects to avoid reprocessing if the recanonicalize process does not complete.

Requirements

Starting the server

Docker

The provided Dockerfile can be used to build and run an image. See the deployment template in deployment/conf/.templates for the environment variables available to configure the service - the deploy.cfg.example file provides documentation for these variables.

docker-compose --build -d can be used to start a MongoDB instance and the auth server in test mode (which can be configured via environment variables in the compose file).

Manually

  • Start mongodb
  • If using mongo auth, create a mongo user
  • cd into the auth2 repo
./gradlew war
mkdir -p jettybase/webapps
cp build/libs/auth2.war jettybase/webapps/ROOT.war
cp templates jettybase/templates
  • copy deploy.cfg.example to deploy.cfg and fill in appropriately
export KB_DEPLOYMENT_CONFIG=<path to deploy.cfg>
cd jettybase
./jettybase$ java -jar -Djetty.port=<port> <path to jetty install>/start.jar

Perform initial setup

Create the administration script:

./gradlew generateManageAuthScript

Set a root password:
build/manage_auth -d <path to deploy.cfg> -r

  • Note that the deploy.cfg file only needs accurate MongoDB connection information for use with the auth CLI.

Login to a local account as ***ROOT*** with the password you set. Create a local account and assign it the create administrator role. That account can then be used to create further administrators (including itself) without needing to login as root. The root account can then be disabled.

To set up alternate login / link environments, see Environments.

Revoking tokens in an emergency

The simple HTML only test UI included with the server supports most administration functions, but revoking all tokens in the service is not included as it has a major impact on systems the auth server supports, essentially shutting them down. If all tokens are revoked, the tokens for every single token type (agent, service, etc.) for every single user in the auth system are removed - the equivalent of clearing the tokens collection in MongoDB.

This feature is intended to be used in an emergency such as many tokens becoming compromised or the system needs to come to a near immediate halt (near immediate since services outside the auth server may cache and accept tokens for some period of time after they're invalidated in auth).

To revoke all tokens, issue the following request to the server (curl used as an example):

curl -X POST --cookie "kbase_session=<admin token>" http://<host>/admin/revokeall

If the token-cookie-name deployment configuration value is not kbase_session change the request to match.

Start & stop server w/o a pid

./jettybase$ java -DSTOP.PORT=8079 -DSTOP.KEY=foo -jar ~/jetty/jetty-distribution-9.3.11.v20160721/start.jar
./jettybase$ java -DSTOP.PORT=8079 -DSTOP.KEY=foo -jar ~/jetty/jetty-distribution-9.3.11.v20160721/start.jar --stop

Omit the stop key to have jetty generate one for you.

Developer notes

Adding and releasing code

  • Adding code
    • All code additions and updates must be made as pull requests directed at the develop branch.
      • All tests must pass and all new code must be covered by tests.
      • All new code must be documented appropriately
        • Javadoc
        • General documentation if appropriate
        • Release notes
  • Releases
    • The master branch is the stable branch. Releases are made from the develop branch to the master branch.
    • Update the version as per the semantic version rules in src/main/java/us/kbase/auth2/Version.java.
    • Tag the version in git and github.

Running tests

  • Copy test.cfg.example to test.cfg and fill in the values appropriately.
    • If it works as is start buying lottery tickets immediately.
  • ./gradlew test

UI

  • Some fields are arbitrary text entered by a user. These fields should be HTML-escaped prior to display. Currently the fields include:
    • Custom role descriptions
    • The reason for why a user account was enabled and disabled.
    • User display names and email addresses.
    • Token names
    • Token custom context

Use common sense when displaying a field from the server regarding whether the field should be html escaped or not.

Templates

All the HTML templates for the test UI are in the /templates directory and are mustache templates.

Exception mapping

In us.kbase.auth2.lib.exceptions:
AuthException and subclasses other than the below - 400
AuthenticationException and subclasses - 401
UnauthorizedException and subclasses - 403
NoDataException and subclasses - 404

JsonMappingException (from Jackson) - 400

Anything else is mapped to 500.

Ancient history

https://github.com/kbaseIncubator/auth2proto