Skip to content
/ oauthly Public

OAuth2 Authorization and Resource Server in Java with Play Framework

License

Notifications You must be signed in to change notification settings

bekce/oauthly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oauthly

Build Status Codacy Badge

chart

OAuth 2.0 Compliant Authorization and Resource Server in Java with Play Framework. Suitable for being the Authorization Server for your software platform, with SSO and social provider login support.

There are a lot of authorization server examples on many platforms, such as Spring Boot, Play Framework, etc, but none works as a full-fledged authorization server. This one does, for free. The functionality is comparable to auth0, will be better in the future (with your PRs, of course).

This project was started as a Spring Boot project (on branch spring-boot) then I have recently fully converted it to Play Framework. The reason for this change is the superior features of Play Framework, and a little bit of curiousity on my side.

Features

  • Uses Play Framework (Java) 2.6.x
  • Fully supported OAuth2 grant types: client credentials, authorization code, resource owner password, refresh token
  • Login, register, profile, user management, client management and authorize client views with Bootstrap
  • Supports logging in with social providers and advanced account linking features
  • Supports sending email confirmation links
  • Utilizes JWT for tokens, authorization codes and cookies
  • Completely stateless server side logic
  • Logged-in users are remembered with long-term safe cookies
  • Multiple client id and secret pairs are supported, managed by a view
  • Customizable expiry times for generated tokens (see application.conf file)
  • Google reCAPTCHA support on endpoints (with @RecaptchaProtected annotation)
  • OAuth2 scopes support
  • MongoDB backend
  • Mailgun API integration for sending emails
  • Uses bcrypt for user passwords, twirl for templating
  • Discourse SSO support, see this

Instructions for local mode

  1. Have a running mongodb instance and sbt installed.
  2. sbt run
  3. Go to http://localhost:9000, register a new account for yourself. All accounts are required to confirm email addresses. To receive emails, you need to get your own mailbox api key. For demo purposes, the confirmation link is logged on console after you register. Copy and paste the link on your browser to finalize account creation. First account will be given admin access.
  4. You can also enable login with Facebook, Google or any other OAuth 2.0 Authorization Server.
    1. For Facebook, go to https://developers.facebook.com/apps/ and create yourself an app with redirect uri http://localhost:9000/oauth/client/facebook/callback, then put its client id and secret to application.conf. You may need some additional settings on your Facebook app. Consult their documentation.
    2. For Google, go to https://console.developers.google.com/apis/credentials and create an OAuth Client ID with redirect url http://localhost:9000/oauth/client/google/callback, then put its client id and secret to application.conf. You will also need to enable Google People API. Consult their documentation.
    3. For any other OAuth 2.0 Authorization Server, see this
  5. By now, you have authenticated yourself as an admin on OAuthly platform. Now you will configure your applications and services (OAuth 2.0 Clients) to connect to OAuthly (OAuth 2.0 Authorization Server). Go to http://localhost:9000/client to create one client, by setting its name and redirect_uri.
  6. Set generated Client ID and Client Secret and following endpoint addresses on your OAuth 2.0 Client Application:
  • Authorize endpoint: http://localhost:9000/oauth/authorize

    Example: curl -v 'http://localhost:9000/oauth/authorize?client_id=vpNS2x3QTVSxjTuWUrY3&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin'

  • Token endpoint: http://localhost:9000/oauth/token (Use POST with FORM parameters)

    Example: curl -v -X POST -d 'grant_type=authorization_code&code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoIjoxMDI1MDQ5NzEzLCJyIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2xvZ2luIiwiZXhwIjoxNTE1MDg0OTM3LCJ2dCI6MywiZyI6IjExbU9tMHVVMEQwOHMxSXo5S3RMIn0.wtLx54iK1kEWhXAVU5gb6AnyPQnN1Qb2r4L-s20TADk&client_id=vpNS2x3QTVSxjTuWUrY3&client_secret=0JPSlNiGKRmcgqidu77s&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin' 'http://localhost:9000/oauth/token'

  • User info endpoint: http://localhost:9000/api/me (Use Authorization: Bearer token header)

    Example: curl -v -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoIjoxMDI1MDQ5NzEzLCJleHAiOjE1MTUwODUxNTYsImdyYW50IjoiMTFtT20wdVUwRDA4czFJejlLdEwiLCJ2dCI6MX0.sl4F-ik9Tstw38JxOSfHYUCi1cN4NxYmqgNCoA0hIbA" http://localhost:9000/api/me

Instructions for production mode

Please first follow the instructions for local mode AND run it on your local machine before attempting this. If you don't have that much time, AT LEAST read them once.

  1. OAuthly must run on a seperate domain. If your domain is example.com, running on oauthly.example.com is recommended.
  2. sbt stage in root folder to prepare distribution.
  3. Move target/universal/stage/oauthly-1.0-SNAPSHOT.zip to your server and extract it to some place.
  4. Set your smtp configurations for play.mailer and set mock=false or create account on http://mailgun.com and get a (free) API key for a valid domain of yours.
  5. Create account on https://www.google.com/recaptcha/admin and get recaptcha.siteKey and recaptcha.secret.
  6. (Optional) If you want to allow Login with Facebook and/or Google, get your keys as specified above.
  7. Prepare conf/prod.conf file from following template. Put random values for jwt.secret and play.http.secret.key.
include "application.conf"

http.port=9000
play.filters.enabled=[
  play.filters.csrf.CSRFFilter,
  play.filters.headers.SecurityHeadersFilter,
  play.filters.hosts.AllowedHostsFilter,
]
play.filters.hosts.allowed = ["oauthly.example.com"]
playjongo.uri="mongodb://127.0.0.1:27017/oauthly"
play.http.secret.key=
jwt.secret=
recaptcha.enabled=true
recaptcha.siteKey=
recaptcha.secret=
use.secure.session.cookie=true
mail.mailgun.key=key-123
mail.mailgun.domain=example.com
mail.mailgun.from="OAuthly <[email protected]>"
brand.name="My Brand"
tos.text="""
Terms of Service content
"""

oauth.providers=[
  {
    key=facebook
    displayName=Facebook
    clientId=
    clientSecret=
    tokenUrl="https://graph.facebook.com/v2.11/oauth/access_token"
    authorizeUrl="https://www.facebook.com/v2.11/dialog/oauth"
    scopes="public_profile email"
    userInfoUrl="https://graph.facebook.com/me?fields=id,name,email"
  }
]
  1. bin/oauthly -Dconfig.resource=prod.conf to start the server.
  2. TLS is a must! You can follow https://www.playframework.com/documentation/2.6.x/ConfiguringHttps for configuring it but I recommend setting up TLS on a reverse proxy like nginx.

Custom OAuth2 Provider

Currently we implement Facebook and Google OAuth2 clients. Every vendor may implement the token and user info retrieval part differently. Follow below steps for a new OAuth2 client implementation.

  1. Put relevant config block in application.conf.
  2. Set tokenRetriever and currentUserIdentifier in AuthorizationServerManager class. Only id is necessary for identifying users in remote system. If you map email addresses in remote system to OAuthly, the confirmation step will be bypassed resulting in a smoother sign-up process.
  3. We use bootstrap-social for provider login buttons, fork it if necessary.

Discourse SSO

OAuthly fully supports Discourse SSO integration. In this configuration, the single source of users becomes oauthly. When Login button is clicked on Discourse, user is redirected to oauthly login page. If the user has already authenticated with oauthly with a long term token, he/she immediately gets redirected back to discourse with user information. Follow the instructions below to configure your system.

  1. Login with admin and go to /discourse
  2. Tick enabled in discourse settings panel, enter sso return url. It is usually http://DISCOURSE_SERVER/session/sso_login
  3. Hit save and copy the generated secret
  4. Open discourse Admin -> Settings -> Login,
    1. 'enable sso' -> true
    2. 'sso url' -> http://OAUTHLY_SERVER/discourse/sso
    3. 'sso secret' -> (secret from step 3)
    4. 'sso overrides username and email' -> true
    5. Users -> 'logout redirect' -> http://OAUTHLY_SERVER/logout
  5. Done, you may test the integration. Remember that the admin account must have the same email address on both systems, or you'll get locked out.

Screenshots (needs update)

login register reset-password profile authorize

TODO (PRs are welcome!)

  • Enable/disable user account function on user management view
  • Possible production example with let's encrypt certificates, docker container and nginx
  • Scope CRUD screen
  • Permissions model
  • More social provider support (github, etc)

About

OAuth2 Authorization and Resource Server in Java with Play Framework

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages