Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oauth1 server support, RSA-SHA1 signature method and important bug fixes #4

Open
wants to merge 4 commits into
base: fork/nbspou
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@

## 2.0.0-alpha
- Added support for implementing OAuth1 servers.
- Implemented RSA-SHA1 signature method.
- Fixed support for signing parameters with multiple values.
- Fixed percent encoding to generate correct signature base strings.

## 1.0.3
- Confirm compatibility with package http 0.12.0

Expand Down
94 changes: 82 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,64 @@
OAuth1
===========
======

[![Build Status](https://travis-ci.org/nbspou/dart-oauth1.svg?branch=fork/nbspou)](https://travis-ci.org/nbspou/dart-oauth1)

"[RFC 5849: The OAuth 1.0 Protocol][rfc5849]" client implementation for dart
OAuth1 library for implementing OAuth1 clients and OAuth1 servers.

Usage
-----
## Supported features

Add to `pubspec.yaml`:
### OAuth 1.0a protocol

```yaml
dependencies:
oauth1: ^1.0.4
```
This library supports OAuth 1.0 as defined by [RFC 5849: The OAuth 1.0
Protocol][rfc5849].

The RFC 5849 was published in 2010. It addresses errata on the
_OAuth Core 1.0 Revision A_ (also known as OAuth1a) that was published
in 2009. That was a revision of the earlier 2007 specification. This
library does not support OAuth 2.0.

### Signature methods

All the signature methods defined in RFC 5849 are supported:

- HMAC-SHA1;
- RSA-SHA1; and
- PLAINTEXT

### Three-legged-OAuth and two-legged-OAuth

This library can be used to implement three-legged-OAuth, as defined
in the first part of RFC 5849. This is where there are three parties
involved: the client, the resource owner and the server.

1. The _client_ obtains a _temporary credential_ from the _server_;
2. The _resource owner_ authorizes the _server_ to grant the client's
access request (as identified by the _temporary credential_);
3. The _client_ uses the _temporary credential_ to request a
_token credential_ from the _server_; and
4. The _client_ accesses protected resources by presenting the _token
credential_.

It can also be used to implement two-legged-OAuth, which only
involves two parties: the client and the server. The client sends a
single request for the protected resource and the server responds with
it.

## Usage

### OAuth1 client

Please use like below.
This library can be used to sign an OAuth1 request. The signed OAuth1
protocol parameters can then be added to a HTTP request and sent to an
OAuth1 server.

Usually, the OAuth1 protocol parameters are sent in a HTTP
"Authorization" header. This library provides a method to format the
parameters for that header. But (less commonly) the parameters can
also be sent as URI query parameters and/or in the body of the HTTP
request.

Here is an example of an OAuth1 client performing three-legged-OAuth:

```dart
import 'dart:io';
Expand Down Expand Up @@ -63,9 +106,36 @@ void main() {
print("Your screen name is " + res.optionalParameters['screen_name']);
});
}

```

In addition, You should save and load the granted token credentials from your drive. Of cource, you don't need to authorize when you did it.
Once the access token has been obtained, it may be used for multiple
requests. The client may find it useful to save the access token for
future use, so it does not have to go through the three-legged-OAuth
process again. But the usefulness of that will depend on the policy of
the server and if access tokens expire or not.

An expanded version of the above code appears in the
_example_client.dart_ example.

### OAuth1 server

An OAuth1 server is a HTTP server that implements the endpoints for
processing OAuth1 requests and for accessing the protected resources.

If it implements the three-legged-OAuth protocol, it needs to issues
and manages both temporary credentials and access tokens. If it
implements the two-legged-OAuth protocol, it only needs to implement
the endpoints for the protected resources (there are no _temporary
credentials_ nor _access tokens_ involved).


This library can be used to parse the information in an OAuth1 HTTP
request and validate the signature. If the signature is valid, then
the server can use the information from the request to perform the
task of the endpoint.

See the _example_server.dart_ for an example of using the library to
create a three-legged-OAuth1 server.


[rfc5849]: http://tools.ietf.org/html/rfc5849
3 changes: 1 addition & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ linter:
# - sort_constructors_first
- sort_pub_dependencies
- sort_unnamed_constructors_first
- super_goes_last
- test_types_in_equals
- throw_in_finally
# - type_annotate_public_apis # subset of always_specify_types
Expand All @@ -142,4 +141,4 @@ linter:
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
# - void_checks # not yet tested
# - void_checks # not yet tested
137 changes: 137 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
OAuth1 Examples
===============

## Introduction

These examples demonstrate the use of the oauth1 library to
implement an OAuth client and an OAuth server.

## Running the examples

1. Run the example OAuth server:

dart example_server.dart

2. In a different terminal, run the client with the URL of the server:

dart example_client.dart -s http://localhost:8080

3. Open the URL printed by the client and authorize the client using
the username "armstrong" and password of "password".

4. Type the PIN from the Web page into the client.

5. The client should print out a message indicating it has successfully
accessed the protected resource.

## Changing behaviour

### Using other signing methods

The example client's default signature method is HMAC-SHA1.
Use the following options to change the signature method:

- `--rsa-sha1` (`-r`) to use the RSA-SHA1 signature method;
- `--plaintext` (`-p`) to use the PLAINTEXT signature method.

The server is capable of using any of the signing methods, as long as
the client credentials it has are suitable. That is, it has a shared
secret for HMAC-SHA1 and PLAINTEXT, or it has an RSA public key for
RSA-SHA1.

### Using other credentials

The client and server both have hard-coded credentials. The default
hard-coded credentials are suitable for all three signature methods.

#### Server

For the server to know about other client credentials, run the server
and provide credential files as additional arguments. Multiple files
can be provided. For example,

dart example_server.dart tester1.secret tester2.public

#### Client

For the client to use another client credential, specify the
credentials file using the `--credentials` (`-c`) option:

```sh
dart example_client.dart -s http://localhost:8080 -c tester2.private --rsa-sha1
```

The client identity can also be specified using the `--client` option,
otherwise it must be specified inside the credentials file. Note:
this only applies to the example client: the credentials file for the
example server must include the client identity (since more than one
credentials files can be registered with the server).

#### Credentials file

A credentials file can contain:

- a user friendly name for the client (as "name");
- client identifier (as "oauth_consumer_key");
- shared secret (as "secret");
- PEM formatted RSA private key; and/or
- PEM formatted RSA public key.

See the example tester credentials files for the expected syntax.

Only PEM formatted RSA public/private keys are recognised.

Note: the client credentials file for the server must not contain an
an RSA private key, since the OAuth server should not have the
client's private key.

### Showing more information

Use the `--verbose` (`-v`) option on the example client and example
server.

### Testing without the manual authorization step

Both the server and client have a `--backdoor` (`-B`) option to make
them easier to test.

Enabling it on both client and server causes the client to
automatically submit a backdoor value for the PIN verifier, which
causes the server to automatically approve the request (as if a
_resource owner_ had visited the Web page and approved the client's
request) and continue to accept the verifier as correct. This avoids
the need to interact with the Web browser to obtain the PIN.

This feature is for testing only. Obviously, a production OAuth server
should not have a backdoor.

### Two-legged-OAuth

The default behaviour is to perform three-legged-OAuth.

To use two-legged-OAuth, run both the example server and example
client with the `--two-legged-oauth` (`-2`) option.

### Testing against other OAuth servers

The example client has options to customise the server endpoints for
the OAuth1 protocol.

The `--server` (`-s`) is a short-hand for setting all three OAuth1
protocol endpoints plus one protected resource endpoint. It assumes
hard-coded paths under that URL. Those hard-coded paths match those
hard-coded in the example server as well as the Twitter API
(i.e. _/oauth/request_token_, _/oauth/authorize_,
_/oauth/access_token_ and _/1.1/statuses/home_timeline.json_).

If those hard-coded parths are not suitable, the full endpoint URLs
can be specified using these options:

- `--temp-uri` (`-T`) for the temporary credential requset URI;
- `--auth-uri` (`-R`) for the resource owner authorization URI;
- `--token-uri` (`-A`) for the (access) token request URI; and
- one or more protected resource URIs as additional arguments.

The default behaviour, if none of these options are used, is to
contact the Twitter API.

Loading