Skip to content

Zowe Authentication and Authorization Service

Petr Plavjanik edited this page Jan 11, 2019 · 17 revisions

Zowe Authentication and Authorization Service

  1. Solution proposal
  2. More details
  3. REST API Specification
  4. JWT Token Format
  5. Authentication to regular endpoints
  6. Login Flow

Solution proposal

The proposal is to implement a temporary solution for Zowe authentication that can be easily replaced by a future security service in z/OSMF. This solution will include support for SSO in meaning that there will be just a single login to Zowe services and initial support for multi-factor authentication (MFA).

An important requirement is that it needs to be used for SSO for Zowe services and z/OSMF.

The proposed security service will provide REST endpoints:

  • for authentication (/login) – accepts a user ID and password and returns JWT token (includes user ID, domain, expiration)
  • to validate the token (/query) – accepts token, returns validation result and details about the token

All the Zowe services (zLUX, API Catalog, CLI) are accessing this service via API gateway to log in and then they provide the token in each HTTP request. The services use the validation endpoint to validate the token provided in HTTP headers.

The Zowe services trust the API gateway (they have a certificate of the CA that signed the server certificate in their trust stores and they all know where API gateway is.

More details

  • zLUX Desktop UI requests the token using /login and then use it for all other calls from the UI or CLI. The back-end services that are receiving the token have to validate it using /query.

  • API Catalog UI in zLUX Desktop will get the token from zLUX desktop

  • z/OSMF will not trust and know about API Gateway. The API gateway needs to provide a valid LTPA token to it when other services will be accessing z/OSMF via gateway and provide JWT token.

    • The temporary solution is going to use current functionality z/OSMF to authenticate and obtain an LTPA token (using /zosmf/info REST endpoint which accepts HTTP Basic authentication – i.e. user ID and password and returns an LTPA token in HTTP response header). The LTPA token will be wrapped in the JWT token. API gateway unwraps it when other services access the z/OSMF and will provide the LTPA token to z/OSMF in a way that z/OSMF expects – i.e. cookie in HTTP request header).

    • The future z/OSMF will trust its JWT tokens and the API gateway will then by just a proxy to the z/OSMF security service

  • Atlas will get the JWT token from the UI and then use it for the calls to z/OSMF. The calls are routed via API gateway that will make sure that real z/OSMF gets LTPA token

  • zLUX server gets the JWT token from the UI and validates it using /query endpoint

All Zowe services are not affected by implementation details of the temporary solution. They use just the token and defined REST API. They will not see a difference between JWT token from the proposed service or future z/OSMF security service.

The implementation of this temporary service will not be a standalone service but just new REST APIs in the API gateway that will be calling z/OSMF and wrapping the LTPA token into a JWT token.

Diagram

REST API Specification

  • /login

    • The /login API lets you perform the following tasks:

      • Authenticate user credentials
      • Optionally change user passwords or passphrases.
      • Optionally set the "expires after" time for the token.
      • Get the authentication token if the login is successful
    • Full URL format:

        POST https://{gatewayHost}:{port}/api/v1/gateway/auth/login
      
    • The login request requires a Basic Authorization header, which provides the credentials of the user logging in:

        Authorization: Basic ZGFhczE6Ym9vdDe1
      

      Follow the standard rules for constructing a Basic Authentication header. For example, the header is usually a base64-encoded string which encodes the concatenated string: "user-id-string" + ":" + "password-or-passphrase-string".

    • The request body contains a single JSON object that provides three optional parameters:

      • (NOT IMPLEMENTED INITIALLY) expiresAfter, which specifies the desired time duration or "life" of the token, and
      • (NOT IMPLEMENTED INITIALLY) newPassword, which specifies a new password or passphrase for the user
    • (NOT IMPLEMENTED INITIALLY) If you do not specify parameter expiresAfter, the token will assume the default value specified by the customer in the security service configuration. If you do specify an expiresAfter value, then it becomes the time duration of the validity or "life" of the token, unless this value exceeds the maximum allowed value as specified in the security service configuration. If you specify an expiresAfter value greater than the maximum allowed, then the maximum value is used for the token. The actual expiration timestamp of the token is returned in the response data (see below). An expiresAfter value of 0 (zero) indicates that the token should be expired immediately; in this case the token will not be valid for use on subsequent REST calls.

    • (NOT IMPLEMENTED INITIALLY) If you specify a newPassword, then the user's password (or passphrase) is changed. This operation authenticates the user with the current credentials, then validates the format of the new password, and if those checks go well, the user's password is changed to the new password.

    • The response is empty body and the token is in a secure HttpOnly cookie named apimlAuthenticationToken{suffix}. {suffix} is a suffix that helps to differentiate different instance of APIML.

    • Error response:

      • Follows the SDK error structure

      • HTTP status codes:

        HTTP Status Code Error Structure Returned Possible Causes
        200 - OK Yes The login was successful. The token is returned in the response object.
        400 - Bad Request No Authorization header is missing, or request body is missing or invalid.
        401 - Unauthorized Yes Login request failed. WWW-Authenticate header contains the domain for which the login is required
        404 - Not Found No The URL is incorrect.
        405 - Method Not Allowed No The method used was something other than POST
  • /query

    • Use the /query API to retrieve the information associated with a token.

    • Full URL:

      GET https://{gatewayHost}:{port}/api/v1/gateway/auth/query
      
    • Headers:

      • JWT token in Authorization Bearer or in a cookie (named apimlAuthenticationToken{suffix} limited to the server)
    • Request Payload:

      • The request body is empty.
    • Response Payload:

      • A response payload is a JSON object. It contains information associated with the token.

        Name Type Description
        domain String The ID of the security domain in which the user and resource are defined. The user has been logged into this domain.
        userId String The logged in user's Identity. This is the same as the user name or ID provided on the Authorization header.
        creation Number Unix timestamp of the login time, in UTC.
        expiration Number Unix timestamp of token expiration, in UTC.

        Sample response:

        {
        "domain": "PRODUCTION",
        "userId": "DAVE",
        "creation": 1497030118362,
        "expiration": 1497116518362
        }
    • Error response:

      • Follows the SDK error structure

      • HTTP status codes:

        HTTP Status Code Error Structure Returned Possible Causes
        200 - OK Yes The login was successful. The token is returned in the response.
        400 - Bad Request No Authorization header is missing, or request body is missing or invalid.
        401 - Unauthorized Yes Query request failed - token is not valid. WWW-Authenticate header contains the domain for which the login is required. JSON response contains more details.
        404 - Not Found No The URL is incorrect.
        405 - Method Not Allowed No The method used was something other than GET

JWT Token Format

The format of the JWT is not an API of the temporary solution. The supported API is the REST API.

Authentication to regular endpoints

Regular endpoints support following authentication methods:

  1. Basic authentication
  2. Authentication with apimlAuthenticationToken cookie
  3. Authorization: Beader <token> header

Login Flow

I want to share with you all the things that need to be considered for the login flow in Zowe. I will try to keep just the important aspects and leave some not so important details.

We have three main personas:

  • Alice – user of the Zowe services and applications
  • Fred – security architect/administrator who is responsible for the security at his shop
  • Victor – an attacker who is trying to get access to something that he is not allowed to

Alice does not want to do login to mainframe applications at all. She has already logged into her computer and she knows that there secure solutions for SSO. But she understands that Fred’s primary goal is to make the assets of their company secure and she accepts the fact that she needs to login to mainframe more frequently.

Fred needs to make the data on mainframe secure. He wants to keep Victor away and Alice in.

Victor is an attacker that gained access to the internal network and now he wants to get to the mainframe. He is happy for any information about topology and security that he did not have before.

Technical aspects:

  • In Zowe, we have chosen a token-based security service for authentication. Successful login results in a token that is safely stored in the browser with a fixed expiration time (configurable by Fred, the default is 12 hours)
  • The login check (authentication) is done by the mainframe security subsystem (SAF). The token validation is done by Zowe security service
  • The authorization to mainframe resources for the user that is authenticated is done by SAF (Zowe does not bypass SAF)
  • The scope of the token can be one application, one mainframe system, one mainframe security domain (several mainframe systems), multiple mainframe security domains. It depends on what Fred wants and configured
  • Multi-factor authentication (MFA) – some mainframe systems can require a second factor (e.g. additional number generated by another device). Token-based security allows that. On z/OS, it implemented in such a way that the second factor is appended to the password. So any application that allows entering of long passwords supports MFA without any changes in the UI. In the future, we would like to have better user experience and ask the user for the second factor in the way how it is done outside of mainframe

Use cases:

  1. Login

    • Alice wants to access some mainframe application and the login screen is displayed when the application does not know who she is
    • The login screen asks her for credentials (username and password)
    • Possible results:
      • Username or password are invalid – Alice needs to check username and enter password again. We should not help Victor by saying that username was valid in case of invalid password.
      • Expired password – we need to tell Alice that the password is expired and allow her to change her password
      • Internal error – we just show generic message “Internal error” and the details are printed to the log. Alice needs to report it to Fred. We can display “log message ID” that will help Fred to locate the details in the log
      • Valid authentication and user has access to the application – we display that starting page of the application or the requested page
      • Valid authentication but the user is not authorized to use the application – we display an error message that makes it clear that she is not use the application and what application and Alice is allowed to login with different credentials. This can happen even after login when she will access different application
  2. Expired token

    • Alice is using application or she accesses application after some time and the token that she has is already expired
    • Login screen should be displayed with an information about what has happened and Alice needs to login again

API Catalog Login Screen wire-frame - https://sketch.cloud/s/w2mKq/KKVyl1

Clone this wiki locally