Giter Club home page Giter Club logo

fabric8-auth's People

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fabric8-auth's Issues

Initial version of Token Storage to cover existing GitHub/OSO token functionality

As the first step we should provide our own implementation to cover all Keycloak functionality currently used by OSIO:

  • Add data model - #132
  • Account linking REST API - #134
  • OSO/GitHub token obtaining REST API (Check if token exists in KC. If not check local DB) - #133
  • Update OSO clients. Configure configmaps/secrets in OSDs.
  • Switch OSIO clients to Auth instead of WIT/KC to obtain tokens - #149
  • Switch UI to new API to link accounts and Update GitHub oauth2 apps - #157
  • Get Token API: Check if token exists in the local DB first. If not check KC - #156

Rollout plan -

  • Rollout the "GET" token API which would currently fetch the token stored in keycloak. ( and store in db for subsequent requests )
  • Rollout the new account linking API
  • Have all clients migrate to the new API for getting tokens.
  • Update linking URL in fabric8-ui Getting Started page & Update redirect URL in the GitHub oauth apps.
  • Get Token API: Check if token exists in the local DB first. If not check KC.

Auth service account

  • New Private/Public keys to be used to sign service account tokens
  • Provide endpoint to expose the public keys #30
  • Load public key from KC instead storing in configuration #29
  • Generate an auth service account token to use it for communicating with WIT when relevant #96
  • Switch WIT to use the public keys exposed by Auth to verify tokens fabric8-services/fabric8-wit#1623

Sync WIT and Auth User/Identity DBs

We should load all existing users and identities from WIT to Auth service DB.
When any user or identity is updated via api.openshift.io we should call auth.openshfit.io to keep both DBs in sync.

It's the first step to sync the DBs. The next step would be to refactor the WIT user/identity model to keep only minimum user/identity information relevant to WIT. Then switch all the client to auth.openshfit.io and update WIT when the relevant user/identity info is updated in auth.openshift.io

Provide endpoint to show the public keys for JWT tokens

We can load this key from KC - #29 and share it with others services so they don't have to hardcode it or load from Keycloak directly.

New /token/keys endpoint:

  • GET /api/token/keys or GET /api/token/keys?format=jwk returns a JSON in the following (JWK) format:
{
  "keys": [
    {
      "alg": "RS256",
      "e": "AQAB",
      "kid": "bNq-BCOR3ev-E6buGSaPrU-0SXX8whhDlmZ6geenkTE",
      "kty": "RSA",
      "n": "vQ8p-HsTMrgcsuIMoOR1LXRhynL9YAU0qoDON6PLKCpdBv0Xy_jnsPjo5DrtUOijuJcID8CR7E0hYpY9MgK5H5pDFwC4lbUVENquHEVS_E0pQSKCIzSmORcIhjYW2-wKfDOVjeudZwdFBIxJ6KpIty_aF78hlUJZuvghFVqoHQYTq_DZOmKjS-PAVLw8FKE3wa_3WU0EkpP-iovRMCkllzxqrcLPIvx-T2gkwe0bn0kTvdMOhTLTN2tuvKrFpVUxVi8RM_V8PtgdKroxnES7SyUqK8rLO830jKJzAYrByQL-sdGuSqInIY_geahQHEGTwMI0CLj6zfhpjSgCflstvw",
      "use": "sig"
    },
    {
      "alg": "RS256",
      "e": "AQAB",
      "kid": "9MLnViaRkhVj1GT9kpWUkwHIwUD-wZfUxR-3CpkE-Xs",
      "kty": "RSA",
      "n": "nwrjH5iTSErw9xUptp6QSFoUfpHUXZ-PaslYSUrpLjw1q27ODSFwmhV4-dAaTMO5chFv_kM36H3ZOyA146nwxBobS723okFaIkshRrf6qgtD6coTHlVUSBTAcwKEjNn4C9jtEpyOl-eSgxhMzRH3bwTIFlLlVMiZf7XVE7P3yuOCpqkk2rdYVSpQWQWKU-ZRywJkYcLwjEYjc70AoNpjO5QnY-Exx98E30iEdPHZpsfNhsjh9Z7IX5TrMYgz7zBTw8-niO_uq3RBaHyIhDbvenbR9Q59d88lbnEeHKgSMe2RQpFR3rxFRkc_64Rn_bMuL_ptNowPqh1P-9GjYzWmPw",
      "use": "sig"
    }
  ]
}
  • GET /api/token/keys?format=pem returns a JSON in the following (PEM-like) format:
{
  "keys": [
    {
      "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvQ8p+HsTMrgcsuIMoOR1LXRhynL9YAU0qoDON6PLKCpdBv0Xy/jnsPjo5DrtUOijuJcID8CR7E0hYpY9MgK5H5pDFwC4lbUVENquHEVS/E0pQSKCIzSmORcIhjYW2+wKfDOVjeudZwdFBIxJ6KpIty/aF78hlUJZuvghFVqoHQYTq/DZOmKjS+PAVLw8FKE3wa/3WU0EkpP+iovRMCkllzxqrcLPIvx+T2gkwe0bn0kTvdMOhTLTN2tuvKrFpVUxVi8RM/V8PtgdKroxnES7SyUqK8rLO830jKJzAYrByQL+sdGuSqInIY/geahQHEGTwMI0CLj6zfhpjSgCflstvwIDAQAB",
      "kid": "bNq-BCOR3ev-E6buGSaPrU-0SXX8whhDlmZ6geenkTE"
    },
    {
      "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnwrjH5iTSErw9xUptp6QSFoUfpHUXZ+PaslYSUrpLjw1q27ODSFwmhV4+dAaTMO5chFv/kM36H3ZOyA146nwxBobS723okFaIkshRrf6qgtD6coTHlVUSBTAcwKEjNn4C9jtEpyOl+eSgxhMzRH3bwTIFlLlVMiZf7XVE7P3yuOCpqkk2rdYVSpQWQWKU+ZRywJkYcLwjEYjc70AoNpjO5QnY+Exx98E30iEdPHZpsfNhsjh9Z7IX5TrMYgz7zBTw8+niO/uq3RBaHyIhDbvenbR9Q59d88lbnEeHKgSMe2RQpFR3rxFRkc/64Rn/bMuL/ptNowPqh1P+9GjYzWmPwIDAQAB",
      "kid": "9MLnViaRkhVj1GT9kpWUkwHIwUD-wZfUxR-3CpkE-Xs"
    }
  ]
}

Load public key from KC instead storing in configuration

We don't have to store the public key in our configuration. We can load it from KC when starting and then check it regularly in case it's changed:
We can use the following endpoint to load the key:
https://sso.openshift.io/auth/realms/fabric8/protocol/openid-connect/certs

We would need to convert the JWK from this endpoint to a pem key

https://tools.ietf.org/html/rfc7517
https://keycloak.gitbooks.io/documentation/securing_apps/topics/oidc/oidc-generic.html
https://play.golang.org/p/mLpOxS-5Fy

Implement resource registration endpoint functionality

This endpoint will be used by WIT and other resource servers to register resources for protection. We will follow the UMA specification for this, with the following enhancements:

  1. Support for specifying the "resource_id", instead of having the authorization service generate one.
  2. Support for specifying a "parent_resource_id", to allow another resource of the same resource type to be delegated as the parent of the new resource. This will allow permissions to be inherited from parent resources to its child resources, and so forth down the inheritance chain.

Here's an example request:

POST /resource/ HTTP/1.1 Content-Type: application/json
Authorization: Bearer MHg3OUZEQkZBMjcx
...
{  
   "resource_scopes":[  
      "read-public",
      "post-updates",
      "read-private",
      "http://www.example.com/scopes/all"
   ],
   "icon_uri":"http://www.example.com/icons/sharesocial.png",
   "name":"Tweedl Social Service",
   "type":"http://www.example.com/rsrcs/socialstream/140-compatible",
   "parent_resource_id":"KX30-1234",
   “resource_id”:”aaaa-bbbb-cccc-dddd-9999-8888-7777-6666”
}

And here is a successful response:

HTTP/1.1 201 Created
Content-Type: application/json
Location: /rreg/KX3A-39WE
...
{  
   "_id":"KX3A-39WE",
   "user_access_policy_uri":"http://as.example.com/rs/222/resource/KX3A-39WE/policy"
}

Migrate from WIT to Auth

  • Start calling Auth from WIT when users are logged in or updated. So, we update all users/identities in Auth if related changes are made in WIT. We also should stop creating/deleting Keycloak resources when a space is created/deleted in WIT. We should call Auth (from WIT) to create/delete resources instead. WIT is still an entry point for all user/identity/login/etc request.
  • Copy all existing users/identities/space resources from WIT DB to Auth DB
  • Stop using WIT for login, user updates, etc and switch all clients (UI) to Auth for that. Auth becomes our entry point for all these requests instead of WIT. Start updating user/identity in WIT when relevant changes are made in Auth.
  • Refactor the WIT user/identity model to keep only minimum user/identity information relevant to WIT.

Migrate space authorization from WIT to Auth

  • Delegate Keycloak space resource creation from WIT to Auth - #27
  • Copy already existing Space Resources entities from WIT DB to Auth - #75
  • Switch UI from using WIT REST API to Auth REST API to manage collaborators Moved to #127
  • Drop Space Resources table and clean up all related code in WIT

When unapproved users are logging in then redirect to a page with proper explanation what to do

If unapproved user tries to login we currently redirect to the OSIO/OSO registration page. We set this redirect URL via F8_AUTH_NOTAPPROVED_REDIRECT env var.
It can be confusing for users. Especially for user which have already registered and are waiting for approving.
We should create a dedicated page in openshiftio app with some proper explanation what is wrong and what user can do about it and redirect to that page instead.

Ask for GitHub scopes when we really need them

Currently we ask users to link their GitHub accounts right after the first login. And we ask for full access to the user's GitHub account.
We should ask users to link GitHub when we actually need it (for example if only planner is used then we don't need GitHub account).
We also could ask for particular permissions/scopes instead of asking for full access. For example could ask for read access only until we really need to write something. Then we ask for write access. Etc.

So, our token management/storage API should support permission/scope elevation. Technically we could implement it via multiple GitHub links (one link per scope).

Logout users before login

  1. User has two RHD accounts. [email protected] and [email protected]
  2. User is approved in OSIO as [email protected]
  3. User is logged-in to RHD as [email protected]
  4. If user clicks on login button on OSIO then RHD won't ask for any credentials because the user is already logged-in to RHD as [email protected] so user will be logged-in to OSIO as [email protected]. The only way for user to login as [email protected] is to go to developers.redhat.com directly and logout there. And even worse it may be required to go to sso.openshift.io and logout there.

Instead we could logout user from RHD and sso.openshift.io every time when a user is trying to login to OSIO.

The easiest way to do it is probably redirect user to https://api.openshift.io/api/logout?redirect=https%3A%2F%2Fapi.openshift.io%2Fapi%2Flogin%2Fauthorize%3Fredirect%3Dhttps%253A%252F%252Fopenshift.io instead of https://api.openshift.io/api/login/authorize

Rename endpoints

/api/user (don't change)
/api/users (don't change)
/api/status (don't change)

/api/login/authorize -----> /api/login
/api/login/generate -----> /api/token/generate
/api/login/refresh -----> /api/token/refresh
/api/login/link -----> /api/link
/api/login/linksession -----> /api/link/session
/api/login/linkcallback -----> /api/link/callback

/api/logout (don't change)

/api/spaces/:spaceID/collaborators/:identityID (don't change)
/api/spaces/:spaceID (don't change)

/api/search/users (don't change)

Migrate User/Identity management from WIT to Auth

( Based on Aug 31st's discussion between @alexeykazakov and sbose )

Phase 1 - continue using WIT , but add support in AUTH. : #26

  • Add support in WIT for creating user/identity through the UPDATE API.
  • On successful login using Auth service, If user is present in Auth DB, Add support in Auth Login workflow to call "update user api" of WIT, .
  • On successful login using Auth service, If user is NOT present in Auth DB, Add support in Auth Login workflow to 'GET user profile info' from WIT. After writing to AUTH DB, call "User update api" of WIT to sync the updated user profile info.
  • When user profile is updated in Auth call WIT to update the user in the WIT DB.

Phase 2 - start using the Auth service : #26

Phase 3 - Migrate data

  • Migrate user data from WIT db to AUTH db - this is a db admin task, #25

Phase 4 - Switch UI to AUTH

  • Switch UI (openshiftio app, fabric8-ui, planner) from WIT API to Auth API for /login, /logout, /refresh, /linksession, /user, /users:id, /spaces/:spaceID/collaborators
    Moved to #127

Phase 5 - Clean up WIT

Support offline token generation

We should add an optional param to our login API to issue an offline token instead of regular access token during login.

If scope=offline_access param is added to the authentication request then the offline token will be issued instead of a regular refresh token.

Delegate userProfile+login requests from WIT to AUTH

Login:
Delegate actual login to Auth when WIT login is called. WIT will need to keep creating users/identities in the WIT DB when login is called.

User profile updates:
Call the corresponding Auth API to update users/identities when the user/identity is updated in WIT. If user doesn't exist in Auth then Auth should just ignore such a request (it may happen if it's an old user created before migration).

WIT should pass a special parameter with all Auth requests to let Auth know that these requests are cumming from WIT (we will need it later when we switch UI to Auth and start notifying WIT about new/updated users to avoid an endless loop).

Part of #79

Implement Hierarchy-based resource queries

This feature is intended to add required functions to the ResourceRepository DAO to allow advanced querying of resources, for example listing resources which are "child" resources of a specified parent.

Create tests to cover full auth flow

Currently our tests cover only the first part of the flow when we call /api/login/authorize to create a state and redirect to KC. We need to cover the second part when after successful authentication KC redirects back to /api/login/authorize and passing the state from the first call.

Moved from fabric8-services/fabric8-wit#1277

Keycloak operation mode should be configurable via env vars.

It's follow up on fabric8-services/keycloak-deployment#45

  1. It should be possible to configure the clustered/standalone mode depending on env (both Cluster mode and the number of replicas bc it will fail if there is more then 1 replica in standalone mode)
  2. There should be the default values (clustered mode + 3 replicas). If the env vars is not set in particular environment then the default ones are used.
  3. Devs should be able to change the default values.

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.