Info e-teenuse arendajatele
HarID uses OpenID Connect with OAuth 2.0 protocol (YouTube short intro) for authentication and authorization. For security implications of getting the implementation correct, we require you to use OAuth 2.0 libraries when interacting with HarID endpoints. Best practice would be to use well written code provided by others - it will help you protect yourself and your users.
E-service registration
Before you can start sending OpenID/OAuth requests, you have to register your e-service.
Please contact with HarID support (harid@harno.ee) and provide following information:
1. Your organisation name and registration number.
2. Your E-service return urls where HarID forwards back (you can add multiple urls if needed).
After that we can add you to our test-environment (test.harid.ee) and provide you with our OpenID client credentials.
Quick technical configuration parameters in JSON format
Test environment (GET request): https://test.harid.ee/.well-known/openid-configuration
Live environment (GET request): https://harid.ee/.well-known/openid-configuration
OpenID/OAuth technical info
Technical configuration parameters in JSON format:
You can get the latest info for test environment at (GET request) : https://test.harid.ee/.well-known/openid-configuration
You can get the latest info for live environment at (GET request): https://harid.ee/.well-known/openid-configuration
{
"issuer": "https://harid.ee",
"authorization_endpoint": "https://harid.ee/et/authorizations/new",
"jwks_uri": "https://harid.ee/jwks.json",
"response_types_supported": [
"code", "token", "id_token", "code token", "code id_token", "id_token token", "code id_token token"
],
"subject_types_supported": [ "public" ],
"id_token_signing_alg_values_supported": [ "RS256" ],
"token_endpoint": "https://harid.ee/et/access_tokens",
"userinfo_endpoint": "https://harid.ee/et/user_info",
"registration_endpoint": "https://harid.ee/et/connect/client",
"scopes_supported": [
"personal_code", "phone", "email", "profile", "openid", "roles", "session_type"
], "grant_types_supported": [ "authorization_code", "implicit" ],
"request_object_signing_alg_values_supported": [ "HS256", "HS384", "HS512" ],
"token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ],
"claims_supported": [ "sub", "iss", "name", "email", "phone_number", "personal_code", "roles" ]
}
Data attributes
Exchange code for access token and ID token:
access_token |
A token that can be sent to HarID. |
id_token |
Identity information (JWT) about the user that is digitally signed by HarID. |
expires_in |
The remaining lifetime of the access token. |
token_type |
Identifies the type of token returned. At this time, this field always has the value 'Bearer'. |
Obtain user information from the ID token:
Example response in json format:
{ "sub": "5727bdad-6f71-4b99-8730-6d66170afa41", "name": "Example User", "given_name": "Example", "family_name": "User", "email": "user@example.com", "email_verified": true, "personal_code": "EE:EID:50701124378", "personal_code_verified": true, "strong_session": false, "roles": [ { "marker": "student", "active": true, "start_date": "2018-01-17", "end_date": null, "name_et": "Õpilane", "name_en": "Student", "name_ru": "student", "desc_et": null, "desc_en": null, "desc_ru": null, "provider_ehis_id": "293", "provider_reg_nr": "75014445", "provider_name": "Keila ühisgümnaasium", "created_at": "2018-01-17T16:25:50+02:00", "updated_at": "2018-01-17T16:27:55+02:00", "student_grade": "6", "student_parallel": "A" }, { "marker": "faculty", "active": null, "start_date": "2018-10-09", "end_date": null, "name_et": "faculty", "name_en": "Faculty", "name_ru": "faculty", "desc_et": null, "desc_en": null, "desc_ru": null, "provider_ehis_id": "223", "provider_reg_nr": "75012452", "provider_name": "Ääsmäe põhikool", "created_at": "2018-10-09T13:44:13+03:00", "updated_at": "2018-10-09T13:44:13+03:00" }, { "marker": "library-walk-in", "active": null, "start_date": "2018-10-09", "end_date": null, "name_et": "library-walk-in", "name_en": "Library-walk-in", "name_ru": "library-walk-in", "desc_et": null, "desc_en": null, "desc_ru": null, "provider_ehis_id": null, "provider_reg_nr": "75012452", "provider_name": "Ääsmäe põhikool", "created_at": "2018-10-09T13:44:13+03:00", "updated_at": "2018-10-09T13:44:13+03:00" }, { "marker": "student", "active": true, "start_date": "2018-12-13", "end_date": null, "name_et": "student", "name_en": "Student", "name_ru": "student", "desc_et": null, "desc_en": null, "desc_ru": null, "provider_ehis_id": "214", "provider_reg_nr": "75004429", "provider_name": "Albu põhikool", "created_at": "2018-12-13T14:42:40+02:00", "updated_at": "2018-12-14T19:13:54+02:00", "student_grade": "5", "student_parallel": null } ], "ui_locales": "et", "custodies": [ { "name": "Hernes Hernes", "given_name": "Hernes", "family_name": "Hernes", "email": "priit.tark+020@gmail.com", "email_verified": true, "personal_code": "EE:EID:60005050011", "personal_code_verified": false, "roles": [ { "marker": "student", "active": true, "start_date": "2018-12-13", "end_date": null, "name_et": "Õpilane", "name_en": "Student", "name_ru": "student", "desc_et": null, "desc_en": null, "desc_ru": null, "provider_ehis_id": "214", "provider_reg_nr": "75004429", "provider_name": "Albu põhikool", "created_at": "2018-12-13T14:42:40+02:00", "updated_at": "2018-12-14T19:13:54+02:00", "student_grade": "5", "student_parallel": null } ] }, { "name": "Loos Loos", "given_name": "Loos", "family_name": "Loos", "email": "priit.tark+011@gmail.com", "email_verified": true, "personal_code": "EE:EID:38612232328", "personal_code_verified": false, "roles": [ ] } ] }
}
NB! If client does not require scope, HarID does not return scope attributes.
All attributes:
Scope | Attribute | Description |
openid |
sub |
Required scope, always include it. An identifier for the user, unique for HarID accounts and never reused. HarID account can have multiple emails at different points in time, but the sub value is never changed. Use sub within your e-service as the unique-identifier key for the user. |
profile |
name |
The user's full name. |
|
The user's email address. This may not be unique and is not suitable for use as a primary key. Provided only if your scope included the string "email". |
|
email_verified |
True if the user's e-mail address has been verified; otherwise false. |
|
profile |
ui_locales |
Indicates user preferred user interface locales, example: 'et' for Estonia or 'et en' where Estonia would be preferred over English. |
personal_code |
personal_code |
Mostly Estonia's identity code. Always have prefix with 2 colons. Example EE:EID:11412090004 |
session_type | strong_session |
True if user user last authentication into HarID was done by using strong authentication method such as Mobile-ID or ID-card. You can use standard way by ID token where "arm" value is either "pwd" (password auth) or "pop" (mobiil-ID/ID-card auth). |
roles | roles | User roles, user can have multiple roles |
roles |
roles:marker | Uniq identifier of user role. 'director' => Provider/school director
'faculty' => Provider/school teacher
'student' => Provider/school student
'secretary' => Provider/school secretary
'sysadmin' => Provider/school sysadmin
Three roles are assigned automatically based on EHIS database with following map: EHIS role 'õpilane' => HarID role 'student' EHIS role 'õpetaja' => HarID role 'faculty' EHIS role 'direktor' => HarID role 'director' Provider sysadmin/secretary can manage user roles directly in HarID portal without EHIS change. |
roles |
roles:active | Defines, if role is valid. Only roles with value "true" are valid. |
roles |
roles:start_date | Role start date. Start date does not define alone, if role is active. Role must be also active with value "true" and start date must be in past to determine you can rely on it. |
roles |
roles:end_date | Role end date. End date does not define alone, if role is active. Role must be also active with value "true" and end date must missing or in the future. |
roles |
roles:name_et | Role name in Estonian |
roles |
roles:name_en | Role name in English |
roles |
roles:name_ru | Role name in Russian |
roles |
roles:desc_et | Role description in Estonian |
roles |
roles:desc_en | Role description in English |
roles |
roles:desc_ru | Role description in Russian |
roles |
roles:provider_reg_nr | Provider's (institution (school)) registration number |
roles |
roles:provider_name | Provider (example school) name |
roles |
roles:created_at | Role creation time, format: ISO8601 |
roles |
roles:updated_at | Role updated time, format: ISO8601 |
roles |
roles:student_grade | Only present when user has 'stundet' role, provides grade, example value: '6' |
roles |
roles:student_parallel |
Only present when user has 'stundet' role, provides class parallel info, example: 'A' |
custodies | name | String, full name |
custodies | given_name | First name |
custodies | family_name | Family name |
custodies | ||
custodies | email_verified | Boolean, true or false, Child has verified his/her email |
custodies | personal_code | Child personal code |
custodies | roles | Same attributes as main role attributes. |
NB! If client does not require scope, HarID does not return scope attributes.
NB! During development, when you change scopes, we recommend to log in to HarID and manually remove all previous confirms.
OpenID/OAuth technical error description
Error name |
Error description and debug info |
insufficient_scope |
Insufficient scope error are returned from user_info request. It means e-service request are denied. Any following situation might cause it: 1) E-service has not requested any scopes, thus HarID does not return any info. 2) E-service has not requested mandatory 'openid' scope. Double check your system has requested at least 'openid' scope. 3) E-service has done everything right but end user has denied giving info out. Please login into HarID portal and remove all E-service authorizations because during testing/development you might previously have denied authorization thus HarID refuse to return requested info. It the future, when your e-service change scopes, then all your users current authorizations will be cancelled automatically and all your users must authorize your e-service new scopes. |
OpenID/OAuth technical low-level flow for debugging
You can test/play with a demo client at https://kool.gitlab.eu
HarID service only supports official OAuth 2.0 libraries We provide low-level flow in order to better understand and debug OpenID Connect protocol.
Terms:
- client - Demo Pihlaka school at https://kool.gitlab.eu
- HarID - Demo HarID server at https://harid.gitlab.eu
1. User visits client website and clicks HarID button. Client system will redirect user to HarID system. Please follow protocol defined at RFC6749 4.1.1 Authorization Request. Include all requested scopes (dark text):
GET redirect request:
https://test.harid.ee/et/
2. User logs in to HarID and grant permissions for the autohrization request. HarID redirect user back to client following redirect url (redirect url must register before at HarID support).
3. Client system makes GET request "https://harid.gitlab.eu/.well-known/openid-
POST /et/access_tokens HTTP/1.1
Authorization: Basic MWViNTJjNDc0MmUyNzBkY2ZiNzA5Nj
Content-Type: application/x-www-form-
Content-Length: 167
Host: harid.gitlab.eu
grant_type=authorization_code&
HarID returns access_token:
GET /et/user_info? HTTP/1.1
Authorization: Bearer 981574fe1aeba078a767329e7fcd35
Host: harid.gitlab.eu
Status: 200 OK
Content-Type: application/json
Connection: keep-alive
Status: 200 OK
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000
Pragma: no-cache
X-Request-Id: 46f4bcca-05f5-4b49-9197-
ETag: W/"
X-Runtime: 0.071670
Date: Tue, 14 Apr 2020 08:10:10 GMT
X-Powered-By: Phusion Passenger 6.0.4
Server: nginx/1.14.2 + Phusion Passenger 6.0.4
Content-Length: 0
{"access_token":"
4. Client makes now user_info request with access_token as follows:
GET /et/user_info? HTTP/1.1
Authorization: Bearer 981574fe1aeba078a767329e7fcd35
Host: harid.gitlab.eu
HarID returns:
Status: 200 OK
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Status: 200 OK
Cache-Control: max-age=0, private, must-revalidate
Strict-Transport-Security: max-age=31536000
X-XSS-Protection: 1; mode=block
X-Request-Id: 9088d5ac-755f-4079-8f7f-
ETag: W/"
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.033594
X-Content-Type-Options: nosniff
Date: Tue, 14 Apr 2020 08:10:10 GMT
X-Powered-By: Phusion Passenger 6.0.4
Server: nginx/1.14.2 + Phusion Passenger 6.0.4
Content-Length: 0
{"sub":"e86ef592-9262-489f-
rade":null,"student_parallel":