/hawkular-accounts

Authorization system in Hawkular

Primary LanguageJava

Hawkular Accounts

Warning
Hawkular Accounts is deprecated. This repository can still be used as reference, but it’s not currently being used by any Hawkular component.

Hawkular Accounts is the user/organization module for Hawkular projects. It provides the registration feature, setting up of organizations and related features. The main registration and user login is provided by Keycloak, while organizations and permissions are implemented in Hawkular Accounts itself.

Hawkular is a monitoring suite, that consists of several sub-projects for storing of metrics, alerting on incoming events and more. Those projects are developed in their own GitHub repositories.

Build Status

About Accounts

The project is divided into several modules. More information about the individual modules can be found in the respective module’s README files.

  • accounts: the REST backend, handling the actions from the Hawkular Accounts UI.

  • api: the components that are intended to be consumed by other Hawkular components.

  • common: some common code, of internal consumption by Accounts components

  • dist: assembles a complete Wildfly with Keycloak and Hawkular Accounts, suitable for isolated development/testing.

  • events-backend: the REST backend for event processing (login, logout, …​)

  • events-listener: JMS-to-CDI bridge for Accounts events, for consumers of Accounts

  • integration-tests: tests that should exercise features (like, "create an offline token")

  • jaxb-adapters: common JAXB adapters for REST backends

  • keycloak-event-listener-*: bridges between Keycloak events and our events backend

  • sample: a sample on how to integrate Accounts into other Hawkular projects.

  • sample-websocket-backend: with -frontend, serves as an example of how to use Accounts for Auth/z in WebSockets

  • sample-websocket-frontend: for usage with sample-websocket-backend

  • sample-websocket-secured: example of how to deploy a secured websocket and its frontend in one module

  • secret-store: the REST backend for generating key/secret tokens backed by Keycloak Offline tokens

  • secret-store-api: components that are intended to be consumed by other Hawkular components

  • undertow-filter: for converting the key/secret tokens into OAuth Access tokens

  • websocket-api: the API for securing WebSockets

The user interface for Hawkular Accounts is located directly in the hawkular main project, under the "console" module.

Basic usage

First, add the API as a dependency:

<dependency>
  <groupId>org.hawkular.accounts</groupId>
  <artifactId>hawkular-accounts-api</artifactId>
  <version>${project.version}</version>
</dependency>

With that, you can now inject the permission checker and other parts of the API directly into your EJBs and other managed beans.

Hawkular Accounts is based on the following concepts:

  • Resource - something that you want to protect; it might be an Alert, an Inventory item, a Metric, …​

  • Persona - either a User or an Organization. A real User can be impersonating an Organization, so, this Organization would be the current Persona. In most cases, the current Persona corresponds to an intuitive notion of the "current user" or "current tenant".

  • User - a real user of the application. In most cases, consumers of Hawkular Accounts do not need to deal directly with users.

  • Organization - a non-user which has an Owner and a set of Members. In most cases, consumers of Hawkular Accounts do not need to deal directly with organizations.

  • Owner - owns a Resource, and can be (currently) either a Hawkular User or an Organization.

  • Member - a User or Organization that can be part of an Organization.

Note that the main Accounts API allows an Organization to be the Owner of another Organization. As some Hawkular components might not be able to deal with this scenario, however, this is currently blocked from the REST endpoint. This effectively means that organizations cannot create sub organizations.

To retrieve the current Persona:

@Stateless
class FooService {
    @Inject
    Instance<Persona> persona;
}

In order to check if a Persona has access to a given Resource, a record of this resource should exist in Hawkular Accounts. For instance, if you need to protect a metric, you need to:

  • Create a Resource with a unique key (possibly the same ID you have in your persistent storage), specifying the Owner (usually, the current Persona).

  • Later on, you can check if the current Persona (or whichever Persona relevant to you) has access to the resource, via PermissionChecker.

Example:

@Stateless
class FooService {
    @Inject
    Instance<Persona> personaInstance;

    @Inject
    PermissionChecker permissionChecker;

    @Inject
    ResourceService resourceService;

    @Inject
    @NamedOperation("foo-read")
    Operation operationRead;

    public void createFoo() {
        Foo foo = new Foo(id); // this is your business resource

        // the ID can be anything that is unique. When omitted, a new UUID is created and you'll be responsible for
        // storing it somewhere and informing it next time you need access to this resource. Also, we need to
        // explicitly know who is the owner.
        resourceService.create(foo.getId(), personaInstance.get());

        // your storage might be Cassandra, JPA-based storage, in memory map, ...
        storage.persist(foo);
    }

    public Foo getFoo(String id) {
        Foo foo = storage.getFoo(id); // this is your business resource

        // when omitted, the user is assumed to be the current user on the permission checker
        if (permissionChecker.isAllowedTo(operationRead, foo.getId())) {
            // return it to the user
        } else {
            // return a forbidden message
        }
    }
}

Operations and Roles

As a one-time setup, the permission set needs to be configured. With that, a list of operations needs to be provided, as well as which roles are allowed to perform those operations. To facilitate this procedure, the OrganizationService can be used as a @Singleton @Startup EJB, with the setup on a @PostConstruct method. Another possible approach, if you need to have control on the ordering of the startup items, is to implement it as a ServletContextListener. You might refer to the SetupOperations on the sample module, which uses the @Singleton @Startup approach or SetupHawkularAccountsImpl on the accounts module, which uses the ServletContextListener approach.

Warning
Keep in mind that this setup is supposed to run only once during the lifecycle of your deployed module. By nature, you might have several operations, so, your transaction might run for a longer period of time than normal transactions. If you have concurrent calls to your setup procedure, one transaction might overlap the other, causing data consistency exceptions.
operationService
        .setup("organization-create")
        .add("Monitor") // means: all roles
        .persist()

        .setup("organization-read")
        .add("Maintainer")
        .persist()

        .setup("organization-delete")
        .add("SuperUser")
        .persist()

        .setup("organization-update")
        .add("Maintainer")
        .persist();

Or, if you need to hold on to the operations that have been created in @PostConstruct, you can replace persist() with make(). E.g.:

   createOperation = operationService.setup("organization-create").add("Monitor").make();
   updateOperation = operationService.setup("organization-update").add("Administrator").make();

Hawkular Accounts ships with the same roles as Wildfly and with the same rules (ie: SuperUser will be given permission to perform operations marked as allowed for "user with at least Monitor role"). So, adding the role "Monitor" during the setup will automatically add all other roles to it.

Note as well that if the set of roles for a given operation has not changed from what we currently have in the database, nothing is performed.

More about the Wildfly roles can be found in this blog post

How to build Hawkular Accounts from source

The API and backend can be build as a regular Maven project:

$ mvn clean install

To build a distribution with Wildfly and Keycloak, use:

$ mvn clean install

Releasing

To perform a release of Hawkular Accounts, you’ll need push permissions to the GitHub repository and execute the following:

mvn clean
mvn release:prepare release:perform -DautoVersionSubmodules=true

And accept all the default values (for versions and tags).

License

Hawkular Accounts is released under Apache License, Version 2.0 as described in the LICENSE document

   Copyright 2015 Red Hat, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.