All Projects → zalando-stups → Play Zhewbacca

zalando-stups / Play Zhewbacca

Licence: mit
Play! framework library to protect REST endpoint by OAuth2 token verification. Supports Play versions 2.5, 2.6, 2.7

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to Play Zhewbacca

Bhagavadgita
A non-profit initiative to help spread the transcendental wisdom from the Bhagavad Gita to people around the world.
Stars: ✭ 84 (+300%)
Mutual labels:  rest-api, oauth2
Flask Restplus Server Example
Real-life RESTful server example on Flask-RESTplus
Stars: ✭ 1,240 (+5804.76%)
Mutual labels:  rest-api, oauth2
Rest Api Examples
Test and Prototype with Fake Online REST/OAuth 2 APIs Examples
Stars: ✭ 13 (-38.1%)
Mutual labels:  rest-api, oauth2
Play Scala Rest Api Example
Example Play Scala application showing REST API
Stars: ✭ 227 (+980.95%)
Mutual labels:  rest-api, playframework
Restful Api With Laravel Definitive Guide
Repository with the base code for the course "RESTful API with Laravel - Definitive-Guide"
Stars: ✭ 156 (+642.86%)
Mutual labels:  rest-api, oauth2
Ngx Api Utils
ngx-api-utils is a lean library of utilities and helpers to quickly integrate any HTTP API (REST, Ajax, and any other) with Angular.
Stars: ✭ 92 (+338.1%)
Mutual labels:  rest-api, oauth2
Springdoc Openapi
Library for OpenAPI 3 with spring-boot
Stars: ✭ 1,113 (+5200%)
Mutual labels:  rest-api, oauth2
Api Restful Con Laravel Guia Definitiva
Repositorio para el código base del curso "API RESTful con Laravel - Guía Definitiva"
Stars: ✭ 95 (+352.38%)
Mutual labels:  rest-api, oauth2
Mcloud
基于Spring Cloud,实现微服务中常用的基础模块,包括 OAuth2 认证服务,统一注册中心,系统监控中心, 统一配置中心,API网关以及熔断器
Stars: ✭ 185 (+780.95%)
Mutual labels:  rest-api, oauth2
Rest Api With Lumen
Rest API boilerplate for Lumen micro-framework.
Stars: ✭ 464 (+2109.52%)
Mutual labels:  rest-api, oauth2
Django Rest Framework Social Oauth2
python-social-auth and oauth2 support for django-rest-framework
Stars: ✭ 941 (+4380.95%)
Mutual labels:  oauth2
Oauth Demo
Spring Security OAuth2 + MongoDB
Stars: ✭ 7 (-66.67%)
Mutual labels:  oauth2
Sentence Aligner Rust
rest service + frontend to align sentences , in rust
Stars: ✭ 13 (-38.1%)
Mutual labels:  rest-api
Project Dashboard With Django
Agile Project Management dashboard with Django REST and Vue.js
Stars: ✭ 25 (+19.05%)
Mutual labels:  rest-api
Detor
🙊 A simple REST API to identify requests made from TOR network.
Stars: ✭ 26 (+23.81%)
Mutual labels:  rest-api
Apps Android Wikiedudashboard
Access WikiEdu Dashboard from Android App.
Stars: ✭ 20 (-4.76%)
Mutual labels:  rest-api
Pyensemblrest
A wrapper for the EnsEMBL REST API
Stars: ✭ 25 (+19.05%)
Mutual labels:  rest-api
Socialite Mailru
MailRu OAuth2 Provider for Laravel Socialite
Stars: ✭ 25 (+19.05%)
Mutual labels:  oauth2
Rest Client
Stars: ✭ 20 (-4.76%)
Mutual labels:  rest-api
Restforms
Forms adapter for InterSystems Cache
Stars: ✭ 14 (-33.33%)
Mutual labels:  rest-api

Play-security library

Build Status - Master Maven Central codecov.io Codacy Badge MIT licensed

Play! library to protect RESTful resource servers using OAuth2. Supported Play! Framework versions are 2.5.x, 2.6.x, 2.7.x. According to RFC 6749:

The client accesses protected resources by presenting the access token to the resource server. The resource server MUST validate the access token and ensure that it has not expired and that its scope covers the requested resource. The methods used by the resource server to validate the access token (as well as any error responses) are beyond the scope of this specification but generally involve an interaction or coordination between the resource server and the authorization server.

However, the specification does not define the interaction between the authorization server and resource server:

The interaction between the authorization server and resource server is beyond the scope of this specification. The authorization server may be the same server as the resource server or a separate entity.

The library assumes an existence of external server which implements API of Plan B Token Info service and which is responsible for the validation of access tokens. The Plan B Token Info service API is not compatible with OAuth 2.0 Token Introspection, so the library does not cover an interaction with authorization servers which might implement token introspection. However, support of token introspection can be easily added by providing an implementation of org.zalando.zhewbacca.AuthProvider interface. We want to remove coupling to Plan B before the end of Q3 2017 and provide better way to integrate authorization servers (see issue-33).

Note: the library does not validate access tokens on its own.

After successful validation of access token it evaluates access rules defined to access protected resources. For example, it can compare scopes required to access protected resource with scopes associated with the token. So the main goal of this library is to reduces amount of infrastructure code needed to implement proper interaction between resource server and authorization server (in this case Plan B Token Info service) and evaluation of access rules.

Currently the library supports only Bearer access token type. In order to access a protected endpoint clients should pass an Authorization header with the Bearer token in every request. More details you can find in the RFC 6749.

Developers who want to use this library don't need to change their code in order to protect endpoints. All necessary security configurations happen in a separate configuration file. The main difference between this library and similar libraries is that as a user of this library you don't need to couple it with any custom annotations or "actions". This library also provides you kind of a safety net because the access to all endpoints is denied by default regardless of whether they are existing or planned.

The library is used in production in several projects, so you may consider it as reliable and stable.

Core Technical Concepts

  • Non-blocking from top to bottom.
  • Non-intrusive approach for the integration with existing play applications. You don't need to change your code.
  • Declarative security configuration via configuration file.
  • Minimalistic. The library does only one thing, but does it good.
  • Developers friendly. Just plug it in and you are done.
  • Easy to use in tests with AlwaysPassAuthProvider provider.
  • Opinionated design choice: the library relies on Play's toolbox like WS-client from the beginning because it is designed to work exclusively within Play-applications.

We mainly decided to release this library because we saw the needs of OAuth2 protection in almost every microservice we built and because we are not happy to couple our code with any forms of custom security actions or annotations.

Known alternatives

Getting Started

Configure libraries dependencies in your build.sbt:

libraryDependencies += "org.zalando" %% "play-zhewbacca" % "2.7.1"

To configure Development environment:

package modules

import com.google.inject.AbstractModule
import org.zalando.zhewbacca._
import org.zalando.zhewbacca.metrics.{NoOpPluggableMetrics, PluggableMetrics}

class DevModule extends AbstractModule {
  val TestTokenInfo = TokenInfo("", Scope.Default, "token type", "user uid")
  
  override def configure(): Unit = {
    bind(classOf[PluggableMetrics]).to(classOf[NoOpPluggableMetrics])
    bind(classOf[AuthProvider]).toInstance(new AlwaysPassAuthProvider(TestTokenInfo))
  }
  
}

For Production environment use:

package modules

import com.google.inject.{ TypeLiteral, AbstractModule }
import org.zalando.zhewbacca._
import org.zalando.zhewbacca.metrics.{NoOpPluggableMetrics, PluggableMetrics}

import scala.concurrent.Future

class ProdModule extends AbstractModule {

  override def configure(): Unit = {
    bind(classOf[AuthProvider]).to(classOf[OAuth2AuthProvider])
    bind(classOf[PluggableMetrics]).to(classOf[NoOpPluggableMetrics])
    bind(new TypeLiteral[(OAuth2Token) => Future[Option[TokenInfo]]]() {}).to(classOf[IAMClient])
  }

}

By default no metrics mechanism is used. User can implement PluggableMetrics to gather some simple metrics. See org.zalando.zhewbacca.IAMClient to learn what can be measured.

You need to include org.zalando.zhewbacca.SecurityFilter into your applications' filters:

package filters

import javax.inject.Inject
import org.zalando.zhewbacca.SecurityFilter
import play.api.http.HttpFilters
import play.api.mvc.EssentialFilter

class MyFilters @Inject() (securityFilter: SecurityFilter) extends HttpFilters {
  val filters: Seq[EssentialFilter] = Seq(securityFilter)
}

and then add play.http.filters = filters.MyFilters line to your application.conf. SecurityFilter rejects any requests to any endpoint which does not have a corresponding rule in the security_rules.conf file.

Example of configuration in application.conf file:

# Full URL for authorization endpoint
authorisation.iam.endpoint = "https://info.services.auth.example.com/oauth2/tokeninfo"

# Maximum number of failures before opening the circuit
authorisation.iam.cb.maxFailures = 4

# Duration after which to consider a call a failure
authorisation.iam.cb.callTimeout = "2 sec"

# Duration after which to attempt to close the circuit
authorisation.iam.cb.resetTimeout = "60 sec"

# Maximum number of retries
authorisation.iam.maxRetries = 3

# Duration in milliseconds of the exponential backoff
authorisation.iam.retry.backoff.duration = "100 ms"

# IAMClient depends on Play internal WS client so it also has to be configured.
# The maximum time to wait when connecting to the remote host.
# Play's default is 120 seconds
play.ws.timeout.connection = "2 sec"

# The maximum time the request can stay idle when connetion is established but waiting for more data
# Play's default is 120 seconds
play.ws.timeout.idle = "2 sec"

# The total time you accept a request to take. It will be interrupted, whatever if the remote host is still sending data.
# Play's default is none, to allow stream consuming.
play.ws.timeout.request = "2 sec"

play.http.filters = filters.MyFilters

play.modules.enabled += "modules.ProdModule"

By default this library reads the security configuration from the conf/security_rules.conf file. You can change the file name by specifying a value for the key authorisation.rules.file in your application.conf file.

# This is an example of production-ready configuration security configuration.
# You can copy it from here and paste right into your `conf/security_rules.conf` file.
rules = [
    # All GET requests to /api/my-resource has to have a valid OAuth2 token for scopes: uid, scop1, scope2, scope3
    {
        method: GET
        pathRegex: "/api/my-resource/.*"
        scopes: ["uid", "scope1", "scope2", "scope3"]
    }

    # POST requests to /api/my-resource require only scope2.write scope
    {
        method: POST
        pathRegex: "/api/my-resource/.*"
        scopes: ["scope2.write"]
    }

    # GET requests to /bar resources allowed to be without OAuth2 token
    {
        method: GET
        pathRegex: /bar
        allowed: true
    }

    # 'Catch All' rule will immidiately reject all requests for all other endpoints
    {
        method: GET
        pathRegex: "/.*"
        allowed: false      // this is an example of inline comment
    }
]

The following example demonstrates how you can get access to the Token Info object inside your controller:

package controllers

import javax.inject.Inject

import org.zalando.zhewbacca.TokenInfoConverter._
import org.zalando.zhewbacca.TokenInfo

class SeoDescriptionController @Inject() extends Controller {

  def create(uid: String): Action[AnyContent] = Action { request =>
    val tokenInfo: TokenInfo = request.tokenInfo
    // do something with token info. For example, read user's UID: tokenInfo.userUid
  }
}

Contributing

Your contributions are highly welcome! To start please read the Contributing Guideline.

Contact

Please drop us an email in case of any doubts. The actual list of maintainers with email addresses you can find in the MAINTAINERS file.

License

The MIT License (MIT)

Copyright (c) 2015 Zalando SE

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].