Coder Social home page Coder Social logo

azutoolkit / authly Goto Github PK

View Code? Open in Web Editor NEW
28.0 28.0 1.0 129 KB

OAuth2 Provider Library - Authly is an OAuth2 Library for creating Authorization Servers that follows OAuth2 authorization mechanisms.

License: MIT License

Crystal 100.00%
authorization crystal crystal-lang oauth2 provider shard

authly's People

Contributors

actions-user avatar codacy-badger avatar eliasjpr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

hostari

authly's Issues

Requesting Google and Apple sign in samples

Is your feature request related to a problem? Please describe.
As someone new to oauth implementations, I am interested in adding a Google sign in widget to my crystal web-app. But as there are no provider specific sample, it is difficult for me to use Authly.

Describe the solution you'd like
A simple sample (perhaps in the readme itself) of what an Oauth2 implementation of Google sign in might look like if using Authly.

Describe alternatives you've considered
While there is a sample in Readme, it is very generic and as such hard for people new to oauth to use. Using Google sign as the example, will be far more useful as most people looking to do oauth will be interested in Google (or Apple, github, Fb etc as the providers)

Add support for the PKCE extension

Is your feature request related to a problem? Please describe.
First off: Thanks for creating this library!
Because I want to create an application which native clients should authenticate from, it'd be very important for the security to have the PKCE extension included. (The latest OAuth Security BCP now recommends using PKCE also for server-side apps, as it provides some additional benefits there as well.)

Describe the solution you'd like
Implement PKCE

Describe alternatives you've considered
None

Additional context
None

Authorization Code With PKCE (Proof Key for Code Exchange)

RFC Authorization Code With PKCE

Feature Name: Authorization Code With PKCE (Proof Key for Code Exchange)

Type: Enhancement

Related components: Authorization Code Grant

Summary

The Proof Key for Code Exchange (PKCE, pronounced pixie) extension describes a technique for public clients to mitigate the threat of having the authorization code intercepted. The technique involves the client first creating a secret, and then using that secret again when exchanging the authorization code for an access token. This way if the code is intercepted, it will not be useful since the token request relies on the initial secret.

Motivation

  • OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack.
  • Authly is missing the PKCE extension
  • PKCE has been requested See Issue #5

Detailed Design

Protocal Flow

                                             +-------------------+
                                             |   Authz Server    |
   +--------+                                | +---------------+ |
   |        |--(A)- Authorization Request ---->|               | |
   |        |       + t(code_verifier), t_m  | | Authorization | |
   |        |                                | |    Endpoint   | |
   |        |<-(B)---- Authorization Code -----|               | |
   |        |                                | +---------------+ |
   | Client |                                |                   |
   |        |                                | +---------------+ |
   |        |--(C)-- Access Token Request ---->|               | |
   |        |          + code_verifier       | |    Token      | |
   |        |                                | |   Endpoint    | |
   |        |<-(D)------ Access Token ---------|               | |
   +--------+                                | +---------------+ |
                                             +-------------------+

Step 1 - Client Generates Code Verifier

When the native app begins the authorization request, instead of immediately launching a browser, the client first creates what is known as a “code verifier“. This is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

Create a code_verifier, which is a cryptographically-random key that will eventually be sent to Auth0 to request tokens.

// Dependency: Node.js crypto module
// https://nodejs.org/api/crypto.html#crypto_crypto
function base64URLEncode(str) {
    return str.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}
var code_verifier = base64URLEncode(crypto.randomBytes(32));

Setp 2 - Client Generates Code Challenge

Once the app has generated the code verifier, it uses that to create the code challenge. For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier. Clients that do not have the ability to perform a SHA256 hash are permitted to use the plain code verifier string as the challenge.

Generate a code_challenge from the code_verifier that will be sent to Auth0 to request an authorization_code.

// Dependency: Node.js crypto module
// https://nodejs.org/api/crypto.html#crypto_crypto
function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));

Step 3 - Authorize the User

Now that the client has a code challenge string, it includes that and a parameter that indicates which method was used to generate the challenge (plain or S256) along with the standard parameters of the authorization request. This means a complete authorization request will include the following parameters.

  • response_type=code – indicates that your server expects to receive an authorization code
  • client_id= – The client ID you received when you first created the application
  • redirect_uri= – Indicates the URL to return the user to after authorization is complete, such as org.example.app://redirect
  • state=1234zyx – A random string generated by your application, which you’ll verify later
  • code_challenge=XXXXXXXXX – The code challenge generated as previously described
  • code_challenge_method=S256 – either plain or S256, depending on whether the challenge is the plain verifier string or the SHA256 hash of the string. If this parameter is omitted, the server will assume plain.
<a href="https://YOUR_DOMAIN/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
  code_challenge_method=S256&
  redirect_uri=YOUR_CALLBACK_URL&
  scope=appointments%20contacts&
  audience=appointments:api&
  state=xyzABC123">
  Sign In
</a>

Step 4 - Authorization Response

The authorization server should recognize the code_challenge parameter in the request, and associate that with the authorization code it generates. Either store this in the database along with the authorization code, or if you’re using self-encoded authorization codes then it can be included in the code itself. (See The Authorization Response for details.) The server returns the authorization code as normal, and does not include the challenge in the data returned.

Step 5 - Authorization Code Exchange

The native app will then exchange the authorization code for an access token. In addition to the parameters defined in Authorization Code Request, the client will also send the code_verifier parameter. A complete access token request will include the following parameters:

- `grant_type=authorization_code` – Indicates the grant type of this token request
- `code` – The client will send the authorization code it obtained in the redirect
- `redirect_uri` – The redirect URL that was used in the initial authorization request
- `client_id` – The application’s registered client ID
- `code_verifier` – The code verifier for the PKCE request, that the app originally generated before the authorization request.

In addition to validating the standard parameters, the authorization server will also validate the code_verifier in the request. Since the code_challenge and code_challenge_method were associated with the authorization code initially, the server should already know which method (plain or SHA256) to use to verify the code_verifier.

If the method is plain, then the authorization server needs only to check that the provided code_verifier matches the expected code_challenge string.

If the method is S256, then the authorization server should take the provided code_verifier and transform it using the same method the client will have used initially. This means calculating the SHA256 hash of the verifier and base64-url-encoding it, then comparing it to the stored code_challenge string.

If the verifier matches the expected value, then the server can continue on as normal, issuing an access token and responding appropriately. If there is a problem, then the server responds with an invalid_grant error.

Errors Responses

The authorization server can require that public clients must use the PKCE extension. This is really the only way to allow public clients to have a secure authorization flow without using the client secret. Since the authorization server should know that a specific client ID corresponds to a public client, it can deny authorization requests for public clients that do not contain a code challenge.

If the authorization server requires public clients to use PKCE, and the authorization request is missing the code challenge, then the server should return the error response with error=invalid_request and the error_description or error_uri should explain the nature of the error.

Device Code Grant

Is your feature request related to a problem?
A grant type called Device Code Grant is missing

Describe the solution you'd like
The Device Code grant type is used by browserless or input-constrained devices in the device flow to exchange a previously obtained device code for an access token.

The Device Code grant type value is urn:ietf:params:oauth:grant-type:device_code.

More resources

  • Device Flow Token Request (oauth.com)
  • Device Flow (alexbilbie.com)
  • Device Code Grant on the OAuth 2.0 Playground

Describe alternatives you've considered
None

Additional context
RFC - https://tools.ietf.org/html/rfc8628#section-3.4
OAuth - https://oauth.net/2/grant-types/device-code/
Alex Bible - https://alexbilbie.com/2016/04/oauth-2-device-flow-grant/
Playground - https://www.oauth.com/playground/device-code.html

Implement Token Introspection

When an OAuth 2.0 client makes a request to the resource server, the resource server needs some way to verify the access token. The OAuth 2.0 core spec doesn’t define a specific method of how the resource server should verify access tokens, just mentions that it requires coordination between the resource and authorization servers. In some cases, especially with small services, both endpoints are part of the same system, and can share token information internally such as in a database. In larger systems where the two endpoints are on different servers, this has led to proprietary and non-standard protocols for communicating between the two servers.

The OAuth 2.0 Token Introspection extension defines a protocol that returns information about an access token, intended to be used by resource servers or other internal servers.

Token Introspection Spec

The Token Introspection spec can be found at https://tools.ietf.org/html/rfc7662

Example Request

POST /token_info HTTP/1.1
Host: authorization-server.com
Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN
 
token=c1MGYwNDJiYmYxNDFkZjVkOGI0MSAgLQ

Example Response

Below is an example of the response that the introspection endpoint would return.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
 
{
  "active": true,
  "scope": "read write email",
  "client_id": "J8NFmU4tJVgDxKaJFmXTWvaHO",
  "username": "aaronpk",
  "exp": 1437275311
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.