Skip to content

Commit 2795e28

Browse files
authored
Merge pull request #29 from umbraco/feature/docs
Updated docs
2 parents 5cec448 + 50b9866 commit 2795e28

File tree

1 file changed

+102
-14
lines changed

1 file changed

+102
-14
lines changed

README.md

Lines changed: 102 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
## Aims
44

5-
**Umbraco Authorized Services** is an Umbraco package designed to reduce the effort needed to integrate third party services that require authentication and authorization via an OAuth flow into Umbraco solutions. It's based on the premise that working with these services requires a fair bit of plumbing code to handle creating an authorized connection. This is necessary before the developer working with the service can get to actually using the provided API to implement the business requirements.
5+
**Umbraco Authorized Services** is an Umbraco package designed to reduce the effort needed to integrate third party services that require authentication and authorization via an OAuth or API key based flow into Umbraco solutions. It's based on the premise that working with these services requires a fair bit of plumbing code to handle creating an authorized connection. This is necessary before the developer working with the service can get to actually using the provided API to implement the business requirements.
66

77
Having worked with a few OAuth integrations across different providers, as would be expected, there are quite a few similarities to the flow that needs to be implemented. Steps include:
88

99
- Redirecting to an authentication endpoint.
10-
- Handling the response including an authentication code and exchanging it for an access token.
10+
- Handling the response including an authentication code (or an oauth token and verifier code) and exchanging it for an access token.
1111
- Securely storing the token.
1212
- Including the token in API requests.
1313
- Serializing requests and deserializing the API responses.
1414
- Handling cases where the token has expired and obtaining a new one via a refresh token.
1515

16+
With API key based flows, the process is a little simpler. But you still have to consider secure storage of the key, providing it correctly in API calls and handling serialization tasks.
17+
1618
There are though also differences, across request and response structures and variations in the details of the flow itself.
1719

1820
The idea of the package is to try to implement a single, best practice implementation of working with OAuth that can be customized, via configuration or code, for particular providers.
@@ -23,7 +25,7 @@ For the solution developer, the Umbraco Authorized Services offers two primary f
2325

2426
Firstly there's an tree available in the _Settings_ section of the backoffice, called _Authorized Services_. The tree shows the list of services based on the details provided in configuration.
2527

26-
Each tree entry has a management screen where an administrator can authenticate with an app that has been setup with the service. The status of each service, in terms of whether the authentication and authorization flow has been completed and an access token stored, is shown on this screen.
28+
Each tree entry has a management screen where an administrator can authenticate with an app that has been setup with the service. The status of each service, in terms of whether the authentication and authorization flow has been completed and an access token (or API key) stored, is shown on this screen.
2729

2830
![Backoffice settings screen](https://2904150615-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeCauR3aomRsx2gdckuDO%2Fuploads%2Fgit-blob-d8f49355a2c62920863e5653f7ad97e135fbc7cb%2Fauthorized-services-tree.png?alt=media)
2931

@@ -69,23 +71,45 @@ Details of services available need to be applied to the Umbraco web application'
6971
{
7072
"<serviceAlias>": {
7173
"DisplayName": "",
74+
"AuthenticationMethod": "OAuth2AuthorizationCode|OAuth2ClientCredentials|OAuth1|ApiKey",
75+
"ClientCredentialsProvision": "AuthHeader|RequestBody",
7276
"ApiHost": "",
7377
"IdentityHost": "",
7478
"TokenHost": "",
7579
"RequestIdentityPath": "",
80+
"CanManuallyProvideToken": true|false,
81+
"CanManuallyProvideApiKey": true|false,
82+
"CanExchangeToken": true|false,
83+
"ExchangeTokenProvision": {
84+
"TokenHost": "",
85+
"RequestTokenPath": "",
86+
"TokenGrantType": "",
87+
"RequestRefreshTokenPath": "",
88+
"RefreshTokenGrantType": "",
89+
"ExchangeTokenWhenExpiresWithin": ""
90+
},
7691
"AuthorizationUrlRequiresRedirectUrl": true|false,
7792
"RequestTokenPath": "",
78-
"JsonSerializer": "",
79-
"RequestTokenFormat": "",
93+
"RequestTokenMethod": "GET|POST",
94+
"RequestAuthorizationPath": "",
95+
"JsonSerializer": "Default|JsonNet|SystemTextJson",
96+
"RequestTokenFormat": "Querystring|FormUrlEncoded",
8097
"AuthorizationRequestRequiresAuthorizationHeaderWithBasicToken": true|false,
98+
"ApiKey": "",
99+
"ApiKeyProvision": {
100+
"Method": "HttpHeader|QueryString",
101+
"Key": ""
102+
},
81103
"ClientId": "",
82104
"ClientSecret": "",
83105
"UseProofKeyForCodeExchange": true|false,
84106
"Scopes": "",
107+
"IncludeScopesInAuthorizationRequest": true|false,
85108
"AccessTokenResponseKey": "access_token",
86109
"RefreshTokenResponseKey": "refresh_token",
87110
"ExpiresInResponseKey": "expires_in",
88-
"SampleRequest": ""
111+
"SampleRequest": "",
112+
"RefreshAccessTokenWhenExpiresWithin": ""
89113
}
90114
}
91115
}
@@ -115,6 +139,18 @@ The value contains the following elements:
115139

116140
Provides a friendly name for the service used for identification in the user interface.
117141

142+
###### AuthenticationMethod
143+
144+
Specifies the type of authentication the service will use, from one of the following available options: `OAuth1`, `OAuth2AuthorizationCode`, `OAuth2ClientCredentials` or `ApiKey`.
145+
146+
If no value is provided, it will default to `OAuth2AuthorizationCode`.
147+
148+
###### ClientCredentialsProvision
149+
150+
Specifies the available options for providing credentials in an `OAuth2` flow: `AuthHeader` or `RequestBody`.
151+
152+
This setting is only utilized when the `AuthenticatedMethod` value is configured as `OAuth2ClientCredentials`.
153+
118154
###### ApiHost *
119155

120156
The host name for the service API that will be called to deliver business functionality. E.g. for Github this is `https://api.github.com`.
@@ -131,6 +167,33 @@ Some providers make available a separately hosted service for handling requests
131167

132168
Used, along with `IdentityHost` to construct a URL that the user is redirected to when initiating the authorization of the service via the backoffice. For GitHub, the required value is `/login/oauth/authorize`.
133169

170+
###### CanManuallyProvideToken
171+
172+
Specifies whether the service supports generating of tokens via the provider's developer portal such that an administrator can manually add one via the backoffice.
173+
174+
###### CanManuallyProvideApiKey
175+
176+
Specifies whether an administrator can manually add API keys via the backoffice. You might prefer to use this option instead of storing the key in configuration via the `ApiKey` setting.
177+
178+
###### CanExchangeToken
179+
180+
Specifies whether the access token can be exchanged with a long lived one.
181+
182+
###### ExchangeTokenProvision
183+
184+
Provides a strongly typed configuration for a setup that allows exchanging an access token.
185+
186+
This setting is only utilized when `CanExchangeToken` is set to `true`.
187+
188+
The configuration of exchange tokens includes:
189+
190+
- `TokenHost`
191+
- `RequestTokenPath`
192+
- `TokenGrantType`
193+
- `RequestRefreshTokenPath`
194+
- `RefreshTokenGrantType`
195+
- `ExchangeTokenWhenExpiresWithin`
196+
134197
###### AuthorizationUrlRequiresRedirectUrl
135198

136199
Some providers require a redirect URL to be provided with the authentication request. For others, instead it's necessary to configure this as part of the registered app. The default value if not provided via configuration is `false`, which is sufficient for the GitHub example.
@@ -143,6 +206,10 @@ Used, along with `TokenHost` to construct a URL used for retrieving access token
143206

144207
An enum value that controls how the request to retrieve an access token is formatted. Options are `Querystring` and `FormUrlEncoded`. `Querystring` is the default value and is used for GitHub.
145208

209+
###### RequestAuthorizationPath
210+
211+
Required in `OAuth1` flows for building the service authorization URL.
212+
146213
###### JsonSerializer
147214

148215
An enum value that defines the JSON serializer to use when creating requests and deserializing responses. Options are `Default` and `JsonNet` and `SystemTextJson`.
@@ -156,13 +223,23 @@ An enum value that defines the JSON serializer to use when creating requests and
156223
This flag indicates whether the basic token should be included in the request for access token. If true, a base64 encoding of <clientId>:<clientSecret> will be added to
157224
the authorization header.
158225

226+
###### API Key
227+
228+
Specifies the key a service with `AuthenticationMethod` set to `ApiKey` will use for making authorized requests to the API.
229+
230+
###### ApiKeyProvision
231+
232+
For `ApiKey` authentication methods, options for passing the API key need to be set, by specifying a method: `HttpHeader` or `QueryString` and the name for the key holding the value.
233+
159234
###### ClientId *
160235

161236
This value will be retrieved from the registered service app.
237+
For `OAuth1` flows it matches the `consumer key` value from the registered service app.
162238

163239
###### ClientSecret *
164240

165241
This value will be retrieved from the registered service app. As the name suggests, it should be kept secret and so is probably best not added directly to `appSettings.json` and checked into source control.
242+
For `OAuth1` flows it matches the `consumer secret` value from the registered service app.
166243

167244
###### UseProofKeyForCodeExchange *
168245

@@ -177,6 +254,9 @@ compare it with the previously sent `code_challenge`.
177254

178255
This value will be configured on the service app and retrieved from there. Best practice is to define only the set of permissions that the integration will need. For GitHub, the single scope needed to retrieve details about a repository's contributors is `repo`.
179256

257+
###### IncludeScopesInAuthorizationRequest
258+
Specifies whether the provided scopes should be included in the authorization request body (e.g. `Microsoft`).
259+
180260
###### AccessTokenResponseKey
181261

182262
The expected key for retrieving an access token from a response. If not provided the default `access_token` is assumed.
@@ -193,6 +273,10 @@ The expected key for retrieving the datetime of token expiry from a response. If
193273

194274
An optional sample request can be provided, which can be used to check that an authorized service is functioning as expected from the backoffice. For example, to retrieve the set of contributors to the Umbraco repository hosted at GitHub, this request can be used: `/repos/Umbraco/Umbraco-CMS/contributors`.
195275

276+
###### RefreshAccessTokenWhenExpiresWithin
277+
278+
Specifies a time interval for expiration of access tokens.
279+
196280
### Authorizing a Service
197281

198282
With one or more service configured, it will be available from the items within a tree in the _Settings_ section:
@@ -312,6 +396,10 @@ Responsible for creating an HTTP client used for making authorization requests t
312396

313397
Responsible for creating a dictionary of parameters provided in the request to retrieve an access token from an authorization code. Implemented by `AuthorizationParametersBuilder`.
314398

399+
#### IAuthorizationPayloadBuilder
400+
401+
Responsible for generating the authorization payload used between the authorization and access token requests. Implemented by `AuthorizationPayloadBuilder`.
402+
315403
#### IAuthorizationRequestSender
316404

317405
Responsible for sending the request to retrieve access tokens. Implemented by `AuthorizationRequestSender`, which depends on `IAuthorizationClientFactory`.
@@ -328,6 +416,10 @@ Responsible for building the URL used to instigate the authentication and author
328416

329417
Responsible for creating a request to an authorized service, providing the content and access token. Implemented by `AuthorizedRequestBuilder`.
330418

419+
#### IExchangeTokenParametersBuilder
420+
421+
Responsible for defining the operations building the dictionary of parameters used in exchange token authorization requests. Implemented by `ExchangeTokenParametersBuilder`.
422+
331423
#### IAuthorizedServiceCaller
332424

333425
Responsible for making requests to the authorized services for the purposes of accessing business functionality. This is used by Umbraco solution developers and is described in detail above. Implemented by `AuthorizedServiceCaller`.
@@ -356,14 +448,10 @@ builder.Services.AddUnique<ISecretEncryptor, AesSecretEncryptor>();
356448

357449
Responsible for instantiating a new strongly typed `Token` instance from the service response. Implemented by `TokenFactory`.
358450

359-
#### ITokenStorage
360-
361-
Responsible for storing tokens. Implemented by `InMemoryTokenStorage` and `DatabaseTokenStorage`.
362-
363-
#### IAuthorizedServiceCache
451+
#### IKeyStorage
364452

365-
Responsible for caching data payload. Implemented by `AuthorizedServiceAuthorizationPayloadCache` to store the authorization payload.
453+
Responsible for storing API keys. Implemented by `DatabaseKeyStorage`.
366454

367-
#### IAuthorizedServiceAuthorizationPayloadBuilder
455+
#### ITokenStorage | IOAuth1TokenStorage | IOAuth2TokenStorage
368456

369-
Responsible for generating the authorization payload used between the authorization and access token requests. Implemented by `AuthorizedServiceAuthorizationPayloadBuilder`.
457+
Responsible for storing tokens. Implemented by `InMemoryTokenStorage`, `DatabaseOAuth1TokenStorage` and `DatabaseOAuth2TokenStorage`.

0 commit comments

Comments
 (0)