ine.api.model.4.5.7.source-code.002-AuthenticationAndSecurity.adoc Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of model Show documentation
Show all versions of model Show documentation
Model management tools for the oVirt Engine API.
== Authentication and Security
=== TLS/SSL Certification
The {product-name} API requires Hypertext Transfer Protocol Secure
(HTTPS) footnote:[HTTPS is described in
http://tools.ietf.org/html/rfc2818[RFC 2818 HTTP Over TLS.]] for secure
interaction with client software, such as the SDK and CLI components.
This involves obtaining the
https://en.wikipedia.org/wiki/Certificate_authority[CA] certificate used by the
server, and importing it into the certificate store of your client.
==== Obtaining the CA Certificate
You can obtain the CA certificate from the {engine-name} and transfer it
to the client machine using one of these methods:
Method 1:: The preferred method for obtaining the CA certificate is to use
the `openssl s_client` command line tool to perform a real TLS handshake
with the server, and then extract the certificates that it presents.
Run a command like this:
+
....
$ openssl s_client \
-connect myengine.example.com:443 \
-showcerts \
< /dev/null
....
+
This command will connect to the server and display output similar to
the following:
+
....
CONNECTED(00000003)
depth=1 C = US, O = Example Inc., CN = myengine.example.com.23416
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=US/O=Example Inc./CN=myengine.example.com
i:/C=US/O=Example Inc./CN=myengine.example.com.23416
-----BEGIN CERTIFICATE-----
MIIEaTCCA1GgAwIBAgICEAQwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMx
FTATBgNVBAoTDEV4YW1wbGUgSW5jLjEjMCEGA1UEAxMaZW5naW5lNDEuZXhhbXBs
SVlJe7e5FTEtHJGTAeWWM6dGbsFhip5VXM0gfqg=
-----END CERTIFICATE-----
1 s:/C=US/O=Example Inc./CN=myengine.example.com.23416
i:/C=US/O=Example Inc./CN=myengine.example.com.23416
-----BEGIN CERTIFICATE-----
MIIDxjCCAq6gAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMx
FTATBgNVBAoTDEV4YW1wbGUgSW5jLjEjMCEGA1UEAxMaZW5naW5lNDEuZXhhbXBs
Pkyg1rQHR6ebGQ==
-----END CERTIFICATE-----
....
+
The text between the `-----BEGIN CERTIFICATE-----` and `-----END
CERTIFICATE-----` marks shows the certificates presented by the server.
The first one is the certificate of the server itself, and the last one
is the certificate of the CA. Copy the CA certificate, including the
marks, to the `ca.crt` file. The result should look like this:
+
....
-----BEGIN CERTIFICATE-----
MIIDxjCCAq6gAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMx
FTATBgNVBAoTDEV4YW1wbGUgSW5jLjEjMCEGA1UEAxMaZW5naW5lNDEuZXhhbXBs
Pkyg1rQHR6ebGQ==
-----END CERTIFICATE-----
....
+
IMPORTANT: This is the most reliable method to obtain the CA certificate
used by the server. The rest of the methods described here will
work in most cases, but they will not obtain the correct CA certificate if
it has been manually replaced by the administrator of the server.
Method 2:: If you cannot use the `openssl s_client` method described
above, you can instead use a command line tool to download the CA
certificate from the {engine-name}.
+
Examples of command line tools include `curl` and `wget`, both of which
are available on multiple platforms.
+
If using `curl`:
+
....
$ curl \
--output ca.crt \
'http://myengine.example.com/ovirt-engine/services/pki-resource?resource=ca-certificate&format=X509-PEM-CA'
....
+
If using `wget`:
+
....
$ wget \
--output-document ca.crt \
'http://myengine.example.com/ovirt-engine/services/pki-resource?resource=ca-certificate&format=X509-PEM-CA'
....
Method 3:: Use a web browser to navigate to the certificate located
at:
+
....
https://myengine.example.com/ovirt-engine/services/pki-resource?resource=ca-certificate&format=X509-PEM-CA
....
+
Depending on the chosen browser, the certificate either downloads or
imports into the browser's keystore.
+
. *If the browser downloads the certificate*: save the file as
`ca.crt`.
+
. *If the browser imports the certificate*: export it from the
browser's certification options and save it as `ca.crt`.
Method 4:: Log in to the {engine-name}, export the certificate from the
truststore, and copy it to your client machine.
+
. Log in to the {engine-name} machine as `root`.
+
. Export the certificate from the truststore using the Java
`keytool` management utility:
+
....
# keytool \
-keystore /etc/pki/ovirt-engine/.truststore \
-storepass mypass \
-exportcert \
-alias cacert \
-rfc \
-file ca.crt
....
+
This creates a certificate file called `ca.crt`.
+
. Copy the certificate to the client machine using the `scp`
command:
+
....
$ scp ca.crt [email protected]:/home/myuser/.
....
Each of these methods results in a certificate file named `ca.crt` on
your client machine. You must then import this file into the certificate
store of the client.
==== Importing a Certificate to a Client
Importing a certificate to a client relies on how the client
stores and interprets certificates. See your client documentation for more
information on importing a certificate.
=== Authentication
Any user with a {engine-name} account has access to the API. All
requests must be authenticated using either *OAuth* or basic
authentication, as described below.
==== OAuth Authentication
Since version 4.0 of {product-name} the preferred authentication
mechanism is https://oauth.net/2[OAuth 2.0], as described in
https://tools.ietf.org/html/rfc6749[RFC 6749].
*OAuth* is a sophisticated protocol, with several mechanisms for obtaining
authorization and access tokens. For use with the {product-name}
API, the only supported one is the _Resource Owner Password Credentials
Grant_, as described in https://tools.ietf.org/html/rfc6749#section-4.3[section 4.3]
of RFC 6749.
You must first obtain a _token_, sending the user name and password
to the {engine-name} single sign-on service:
....
POST /ovirt-engine/sso/oauth/token HTTP/1.1
Host: myengine.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
....
The request body must contain the `grant_type`, `scope`, `username`,
and `password` parameters:
.OAuth token request parameters
|===
|Name |Value
|`grant_type`
|`password`
|`scope`
|`ovirt-app-api`
|`username`
|`admin@internal`
|`password`
|`mypassword`
|===
These parameters must be
https://en.wikipedia.org/wiki/Percent-encoding[URL-encoded]. For example,
the `@` character in the user name needs to be encoded as `%40`. The
resulting request body will be something like this:
....
grant_type=password&scope=ovirt-app-api&username=admin%40internal&password=mypassword
....
IMPORTANT: The `scope` parameter is described as optional in the *OAuth*
RFC, but when using it with the {product-name} API it is mandatory, and
its value must be `ovirt-app-api`.
If the user name and password are valid, the {engine-name} single sign-on service
will respond with a JSON document similar to this one:
....
{
"access_token": "fqbR1ftzh8wBCviLxJcYuV5oSDI=",
"token_type": "bearer",
"scope": "...",
...
}
....
For API authentication purposes, the only relevant name/value pair is the
`access_token`. Do not manipulate this in any way; use it exactly as
provided by the SSO service.
Once the token has been obtained, it can be used to perform requests to
the API by including it in the HTTP `Authorization` header, and using the
`Bearer` scheme. For example, to get the list of virtual machines,
send a request like this:
....
GET /ovirt-engine/api/vms HTTP/1.1
Host: myengine.example.com
Accept: application/xml
Authorization: Bearer fqbR1ftzh8wBCviLxJcYuV5oSDI=
....
The token can be used multiple times, for multiple requests, but it will
eventually expire. When it expires, the server will reject the request with
the 401 HTTP response code:
....
HTTP/1.1 401 Unauthorized
....
When this happens, a new token is needed, as the {engine-name} single sign-on
service does not currently support refreshing tokens. A new token can be
requested using the same method described above.
==== Basic Authentication
IMPORTANT: Basic authentication is supported only for backwards
compatibility; it is deprecated since version 4.0 of {product-name},
and will be removed in the future.
Each request uses HTTP Basic Authentication footnote:[Basic
Authentication is described in http://tools.ietf.org/html/rfc2617[RFC
2617 HTTP Authentication: Basic and Digest Access Authentication].] to
encode the credentials. If a request does not include an appropriate
`Authorization` header, the server sends a `401 Authorization Required` response:
....
HEAD /ovirt-engine/api HTTP/1.1
Host: myengine.example.com
HTTP/1.1 401 Authorization Required
....
Request are issued with an `Authorization` header for the specified
realm. Encode an appropriate {engine-name} domain and user
in the supplied credentials with the `username@domain:password`
convention.
The following table shows the process for encoding credentials in
https://tools.ietf.org/html/rfc4648[Base64].
.Encoding credentials for API access
|===
|Item |Value
|User name
|`admin`
|Domain
|`internal`
|Password
|`mypassword`
|Unencoded credentials
|`admin@internal:mypassword`
|Base64 encoded credentials
|`YWRtaW5AaW50ZXJuYWw6bXlwYXNzd29yZA==`
|===
Provide the Base64-encoded credentials as shown:
....
HEAD /ovirt-engine/api HTTP/1.1
Host: myengine.example.com
Authorization: Basic YWRtaW5AaW50ZXJuYWw6bXlwYXNzd29yZA==
HTTP/1.1 200 OK
....
IMPORTANT: Basic authentication involves potentially sensitive
information, such as passwords, sent as plain text. The API requires
Hypertext Transfer Protocol Secure (HTTPS) for transport-level
encryption of plain-text requests.
IMPORTANT: Some Base64 libraries break the result into multiple lines
and terminate each line with a newline character. This breaks the header
and causes a faulty request. The `Authorization` header requires the
encoded credentials on a single line within the header.
==== Authentication Sessions
The API also provides authentication session support. Send an initial request
with authentication details, then send all subsequent requests using a session
cookie to authenticate.
===== Requesting an Authenticated Session
. Send a request with the `Authorization` and `Prefer: persistent-auth`
headers:
+
....
HEAD /ovirt-engine/api HTTP/1.1
Host: myengine.example.com
Authorization: Basic YWRtaW5AaW50ZXJuYWw6bXlwYXNzd29yZA==
Prefer: persistent-auth
HTTP/1.1 200 OK
...
....
+
This returns a response with the following header:
+
....
Set-Cookie: JSESSIONID=5dQja5ubr4yvI2MM2z+LZxrK; Path=/ovirt-engine/api; Secure
....
+
Take note of the `JSESSIONID=` value. In this example the value is
`5dQja5ubr4yvI2MM2z+LZxrK`.
. Send all subsequent requests with the `Prefer: persistent-auth` and
`Cookie` headers with the `JSESSIONID=` value. The `Authorization` header
is no longer needed when using an authenticated session.
+
....
HEAD /ovirt-engine/api HTTP/1.1
Host: myengine.example.com
Prefer: persistent-auth
Cookie: JSESSIONID=5dQja5ubr4yvI2MM2z+LZxrK
HTTP/1.1 200 OK
...
....
+
. When the session is no longer required, perform a request to the
sever without the `Prefer: persistent-auth` header.
+
....
HEAD /ovirt-engine/api HTTP/1.1
Host: myengine.example.com
Authorization: Basic YWRtaW5AaW50ZXJuYWw6bXlwYXNzd29yZA==
HTTP/1.1 200 OK
...
....
+