PHPackages                             hieofone-as/hieofone-as - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. hieofone-as/hieofone-as

ActiveProject[Authentication &amp; Authorization](/categories/authentication)

hieofone-as/hieofone-as
=======================

Health Information Exchange of One Authorization Server.

61306[5 PRs](https://github.com/shihjay2/hieofone-as/pulls)PHP

Since Jan 12Pushed 3y ago8 watchersCompare

[ Source](https://github.com/shihjay2/hieofone-as)[ Packagist](https://packagist.org/packages/hieofone-as/hieofone-as)[ RSS](/packages/hieofone-as-hieofone-as/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependenciesVersions (6)Used By (0)

HIE of One Authorization Server
===============================

[](#hie-of-one-authorization-server)

HIE of One Authorization Server is a simple User Managed Access ([UMA](https://tools.ietf.org/html/draft-hardjono-oauth-umacore-14)) Server that incorporates [OAuth2](https://tools.ietf.org/html/rfc6749) and [OpenID Connect](https://openid.net/connect/) protocols to facilitate the ability of an individual to control and authorize access to his or her health information to clients such as physicians, hospitals, caregivers, and third-party applications.

Installation
------------

[](#installation)

Run the following commands to install:

```
sudo curl -o install.sh https://raw.githubusercontent.com/shihjay2/hieofone-as/master/install.sh
sudo chmod +x install.sh
sudo bash install.sh

```

Dependencies
------------

[](#dependencies)

1. PHP
2. MySQL
3. Apache
4. CURL

Features
--------

[](#features)

1. OAuth2 OpenID Connect compliant server
2. OAuth2 OpenID Connect relying party for Google and Twitter
3. User Managed Access compliant authentication server

How a client registers with the HIE of One Authorization Server
---------------------------------------------------------------

[](#how-a-client-registers-with-the-hie-of-one-authorization-server)

### Requisite conditions:

[](#requisite-conditions)

1. Patient has registered a domain name where the HIE of One Authorization Server is installed (ie domain.xyz)
2. Client software (such as an EHR with a patient portal) has the capability to make HTTPS calls (such as CURL) and is able to process JSON responses.

### Step 1: Announce patient's HIE of One email address and authorization server to the client

[](#step-1-announce-patients-hie-of-one-email-address-and-authorization-server-to-the-client)

Patient submits his or her HIE of One email address () to the client (like a physician), where domain.xyz is the same domain name as where the HIE of One **authorization server** is installed. This can be done, for example, through a EHR patient portal that has a text input that allows processing of the patient's HIE of One email address. Alternatively, the provider would enter this email address in the EHR directly when the patient's chart is open. A negative result results in a 404 error response.

### Step 2: Client verifies patient's authorization server

[](#step-2-client-verifies-patients-authorization-server)

Client submits email address to the following address per [Webfinger protocol](https://tools.ietf.org/html/rfc7033) to confirm validity of the account and email address. Here is an example call (line breaks below are just for display convenience):

```
GET /.well-known/webfinger?
resource=acct:patient@domain.xyz
&rel=http://openid.net/specs/connect/1.0/issuer

```

### Step 3: Client learns authorization server endpoints

[](#step-3-client-learns-authorization-server-endpoints)

Client takes the JSON return (specifically the `href subkey` under `links`) and when appending `.well-known/uma2-configuration` to the URL, like this: , client will see in JSON format all the valid UMA endpoints where client makes calls to initiate a token request, start authorization, request a permission ticket, and make requesting party claims.

### Step 4: Client dynamically registers to the authorization server

[](#step-4-client-dynamically-registers-to-the-authorization-server)

Client makes a call to the `dynamic_client_endpoint` to [register itself](https://tools.ietf.org/html/draft-ietf-oauth-dyn-reg-30). Client will need to store the `client_id` and `client_secret` (such as in a database) going forward. It is important for the client to consider which redirect URIs to use as one of them will need to handle the `claims_redirect_uri` parameter listed here. Being a client only requires that you declare a scope of `uma_authorization`. Here is an example call (line breaks below are just for display convenience):

```
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com

{
	"redirect_uris":[
		"https://client.example.org/callback",
		"https://client.example.org/callback2"]
	"client_name":"My Example Client",
	"logo_uri":"https://client.example.org/logo.png",
	"claims_redirect_uris":[
		"https://client.example.org/callback3"
	],
	"scope": "openid email offline_access uma_authorization"
}

```

### Step 5: Authorize client and retrieve refresh token

[](#step-5-authorize-client-and-retrieve-refresh-token)

As a client, make a call to the `authorization_endpoint`. Make sure as a client that it declares these 2 scopes - uma\_authorization (which defines you as a client requesting access to resources) and offline\_access (so that you can obtain a **refresh token** for future calls without needing the patient to repeat consent online.) Here is an example call (line breaks below are just for display convenience):

```
GET /authorize?
response_type=code
&scope=openid%20profile%20email%20uma_authorization%20offline_access
&client_id=some_client_id
&client_secret=some_client_secret
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Host: server.example.com

```

The patient is then directed to the login page of HIE of One Authorization Server where he/she verifies his/her identity. If successful, the patient will then see a consent screen that verifies that this client will have access to resources registered on his/her authorization server. If the patient accepts, the client is authorized and the client is now registered to the authorization server. From now on, the client is now the **registered client**. ***It is the responsibility of the client to correctly assign the registered client information (client\_id, client\_secret, refresh\_token, authorization server URI) to the correct identity (patient, requesting party).***

How a client becomes a resource server
--------------------------------------

[](#how-a-client-becomes-a-resource-server)

Becoming a resource server is exactly the same steps as above except for the following changes:

### Requisite condition:

[](#requisite-condition)

1. Resource server software has **resources** that pertain to the patient

### Step 4: Client dynamically registers to the authorization server

[](#step-4-client-dynamically-registers-to-the-authorization-server-1)

Resource server makes a call to the `dynamic_client_endpoint` to [register itself](https://tools.ietf.org/html/draft-ietf-oauth-dyn-reg-30). Resource server will need to store the `client_id` and `client_secret` (such as in a database) going forward. It is important for the resource server to consider which redirect URIs to use as one of them will need to handle the `claims_redirect_uri` parameter listed here. Being a resource server requires that you declare a scope of `uma_protection`. Being a resource server also allows it to be client, so a scope declaration can include both `uma_authorization` and `uma_protection`. Here is an example call (line breaks below are just for display convenience):

```
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com

{
	"redirect_uris":[
		"https://rs.example.org/callback",
		"https://rs.example.org/callback2"]
	"client_name":"My Example Resource Server",
	"logo_uri":"https://rs.example.org/logo.png",
	"claims_redirect_uri":[
		"https://rs.example.org/callback3"
	],
	"scope": "openid email offline_access uma_authorization uma_protection"
}

```

### Step 5: Authorize client and retrieve refresh token

[](#step-5-authorize-client-and-retrieve-refresh-token-1)

As a resource server, make a call to the `authorization_endpoint`. Make sure as a resource server that it declares these 2 scopes - uma\_protection (which defines you as a resource server requesting access to serve resources) and offline\_access (so that you can obtain a **refresh token** for future calls without needing the patient to repeat consent online.) Here is an example call (line breaks below are just for display convenience):

```
GET /authorize?
response_type=code
&scope=openid%20profile%20email%20uma_protection%20offline_access
&client_id=some_client_id
&client_secret=some_client_secret
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Frs.example.org%2Fcb HTTP/1.1
Host: server.example.com

```

The patient is then directed to the login page of HIE of One Authorization Server where he/she verifies his/her identity. If successful, the patient will then see a consent screen that verifies that this resource server will have access to his data and will be able to serve resources and register them on his/her authorization server. If the patient accepts, the client is authorized and the client is now registered to the authorization server. From now on, the client is now the **registered resource server**. ***It is the responsibility of the resource server to correctly assign the registered client information (client\_id, client\_secret, refresh\_token, authorization server URI) to the correct identity (patient).***

How a requesting party (such as a physician) obtains authorization to access a resource
---------------------------------------------------------------------------------------

[](#how-a-requesting-party-such-as-a-physician-obtains-authorization-to-access-a-resource)

### Requisite conditions:

[](#requisite-conditions-1)

1. The **authorization server** has a associated **resource server** (such as a patient centric EHR that supports the [FHIR](http://wiki.hl7.org/index.php?title=FHIR) API like [NOSH ChartingSystem](https://github.com/shihjay2/nosh-cs))
2. The **registered client** knows the [FHIR](http://wiki.hl7.org/index.php?title=FHIR) **resource endpoints** such as medication list, problem list, allergy list, encounters, immunizations, binaries) to access/edit these resources.
3. The patient has created policies via the policy API that define which **requesting party** (identified by his/her e-mail address) has permissions to access/edit his/her resources.

### Step 1a: Physician uses the registered client to access the resource server

[](#step-1a-physician-uses-the-registered-client-to-access-the-resource-server)

The client makes an initial call to the **resource endpoint**.

```
GET /fhir/Patient/1 HTTP/1.1
Host: rs.example.com

```

The **resource server** sends a response back with the URI of the **authorization server** (`as_uri` parameter in the `WWW-Authenticate` portion of the return header) and a **permission ticket** (`ticket` in JSON return).

### Step 2a: Client obtains an authorization API token (AAT) from the authorization server

[](#step-2a-client-obtains-an-authorization-api-token-aat-from-the-authorization-server)

The client makes a call to the `token_endpoint` of the **authorizaion server** as such (line breaks below are just for display convenience):

```
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=some_client_id
&client_secret=some_client_secret
&scope=uma_authorization

```

The **authorization API token** is `access_token` in the JSON return which will be used in the `rpt_endpoint`.

### Step 3a: Client makes a call to the authorization server with the permission ticket given by the resource server

[](#step-3a-client-makes-a-call-to-the-authorization-server-with-the-permission-ticket-given-by-the-resource-server)

The client makes a call to the `requesting_party_claims_endpoint` of the **authorization server** and presents the **permission ticket** as such (line breaks below are just for display convenience):

```
GET /rqp_claims?client_id=some_client_id
&state=abc&ticket=016f84e8-f9b9-11e0-bd6f-0021cc6004de
&claims_redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fredirect_claims HTTP/1.1
Host: as.example.com

```

The requesting party will then be directed following this call to the authorization server which will determine the identity of the requesting party where a login screen will be presented. 4 choices of login will exist (going in order of most likely to least)

1. Login with [MDNosh Gateway](https://noshchartingsystem.com/mdnosh_gateway) (a federated physician single-sign-on solution).
2. Login with [Google](https://myaccount.google.com/)
3. Login with [Twitter](https://twitter.com/login)
4. Login with the authorization server (if the physician is a registered user for the authorization server, which is the least likely scenario)

After login, the authorization server checks the login identity email address to the **claim** associated with the resource policy. If there is a match, the requesting party is redirected by the client supplied redirect URL (`claims_redirect_uri` in the above example) with the added `authorization_state` parameter as such (line breaks below are just for display convenience)

```
GET /redirect_claims?&state=abc
&authorization_state=claims_submitted HTTP/1.1
Host: client.example.com

```

### Step 4a: Client makes a call to the authorization server to get a requesting party token

[](#step-4a-client-makes-a-call-to-the-authorization-server-to-get-a-requesting-party-token)

Client makes a call to the `rpt_endpoint` of the **authorization server** supplying the **authorization API token** and the **permission ticket** as such (line breaks below are just for display convenience):

```
POST /authz_request HTTP/1.1
Host: as.example.com
Authorization: Bearer some_authorization_API_token
...
{
	"ticket": "some_permission_ticket"
}

```

The **requesting party token** is `rpt` in the JSON return.

### Step 5a: Client re-accesses resource server

[](#step-5a-client-re-accesses-resource-server)

The client redirects back to the **resource server** with the **requesting party token** attached to the original FHIR **resource endpoint**.

```
GET /fhir/Patient/1 HTTP/1.1
Host: rs.example.com
Authorization: Bearer some_requesting party_token

```

The **resource server** makes calls to the **authorization server** to validate the **requesting party token** through an introspection call. If validated, the resource server then presents the requested FHIR resource to the requesting party.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

If you discover a security vulnerability within HIE of One Authorization Server, please send an e-mail to Michael Chen at shihjay2 at gmail.com. All security vulnerabilities will be promptly addressed.

License
-------

[](#license)

The HIE of One Authorization Server is open-sourced software licensed under the [GNU AGPLv3 license](https://opensource.org/licenses/AGPL-3.0).

###  Health Score

24

—

LowBetter than 31% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 99.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/ef49ea1eaa803843bfe64873381096b717784a46a03195d87770535c3f00e390?d=identicon)[shihjay2](/maintainers/shihjay2)

---

Top Contributors

[![shihjay2](https://avatars.githubusercontent.com/u/2372438?v=4)](https://github.com/shihjay2 "shihjay2 (473 commits)")[![clehner](https://avatars.githubusercontent.com/u/95347?v=4)](https://github.com/clehner "clehner (1 commits)")

### Embed Badge

![Health badge](/badges/hieofone-as-hieofone-as/health.svg)

```
[![Health](https://phpackages.com/badges/hieofone-as-hieofone-as/health.svg)](https://phpackages.com/packages/hieofone-as-hieofone-as)
```

###  Alternatives

[kartik-v/yii2-password

Useful password strength validation utilities for Yii Framework 2.0

761.3M17](/packages/kartik-v-yii2-password)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
