Mixing OAuth 2.0,
Jersey and
Guice to
Build an Ecosystem of Apps
Hermann Burgmeier Matthias Miltz
JavaOne September 2013
Building an Ecosystem
● Co-Innovation with the community
 Mobile platform support
 SaaS model (Chaining of services)
● Provide (REST-)API for your service
● Ease of consumption for 3rd party developers
○ Many OAuth2 client libraries available
● Don’t worry about things that don’t deliver value:
○ Authentication
○ Authorization
Password Anti-Pattern
● Share your user/password directly
o Can you trust the site?
o Do you know if they store it?
o How to revoke access?
● Users get careless about sharing their
password
● No authorization of the requesting site
● No fine grained permissions
● Changing the password
frequently cuts off all sites
OAuth 2.0
● Protocol for authorization - not authentication
● Delegated model
o Fix the password anti-pattern!
o Trust relationship between resource, identity server
and client app
● Official IETF standard since Oct-2012 (http://oauth.net/2/)
● Goal was simplicity:
o Nounces / Signing of requests, anyone?
o No verification code
● Relies heavily on TLS/SSL
OAuth 2.0 - Implementations
● Early implementations by Google, Facebook, Github, etc.
● Java Open Source Server Implementations:
○ OAuth for Spring
○ Apis Authorization Server
○ Apache Oltu
○ Apache CXF
○ Restlet Framework
○ Jersey-OAuth2
■ Available on Github (github/hburgmeier/jerseyoauth2)
■ Based on dependency injection (Guice)
■ Variants for Jersey 1.x and 2.x
■ MIT License
OAuth 2 – Supported Flows
● Authorization Code
○ Strong authentication of the client
○ Trade authorization code for token
● Implicit
○ For clients that can’t keep a secret
● Resource Owner Password Credentials
○ If you and your users trust the client app...
● Client Credentials
○ To replace the common API key / API secret pattern
○ Used by Twitter
OAuth 2 for Mobile Native Apps
● Mobile applications can’t really keep a client secret
● Only two possible flows:
o Authorization Code
 No client secret possible
o Implicit Grant
 No refresh token
 Based on “phony” Redirect-URL
● Standard proposes use of an internal/external browser
Our Demo
● Service to provide last coffee bean price
 REST service returning JSON object
 Implemented using JAX-RS 2.0 and Jersey 2.0
● What we want to do:
 Enable OAuth 2.0 on the service
 Javascript-based client as pure HTML application
• OAuth 2 Implicit Grant
 Integrate external identity provider (Lenovo ID)
 Hosted on OpenShift
Protocol Flow Implicit Grant
HTTP/1.1 302 Found
Location: http://client.example.com/cb#
access_token=mF_9.B5f-4.1JqM&
expires_in=3600
GET /authorize?
response_type=token&
client_id=jsOnlyClientID&
redirect_uri=https://client.example.com/cb
GET /resource/1
Authorization: Bearer mF_9.B5f-4.1JqM
Implementing Implicit Grant in
JavaScript
● Can’t keep a OAuth secret because JavaScript is
visible/debuggable in the browser
● Redirect URI is used for client authentication
● Access Token is transported as URL fragment
● Cross domain HTTP request to access
REST service
o Only works in modern browsers
o Requires a CORS enabled resource server
How to Enable Your Service
@Path("/coffee")
public class CoffeePriceService {
@GET
@Produces({ MediaType.APPLICATION_JSON })
public CoffeePrice get() {
…
}
How to Enable Your Service
@OAuth20
@AllowedScopes(scopes = {"espresso"})
@Path("/coffee")
public class CoffeePriceService {
@GET
@Produces({ MediaType.APPLICATION_JSON })
public CoffeePrice get() {
…
}
JAX-RS / Jersey 2.0 in our Example
public class RestApplication extends Application {
@Inject
public RestApplication(ServiceLocator serviceLocator) {
DynamicConfiguration dc = Injections.getConfiguration(serviceLocator);
Injections.addBinding(Injections.newBinder(DefaultConfiguration.class).to(IRSConfiguration.class), dc);
Injections.addBinding(Injections.newBinder(AccessTokenVerifier.class).to(IAccessTokenVerifier.class), dc);
Injections.addBinding(Injections.newBinder(RequestFactory.class).to(IRequestFactory.class), dc);
dc.commit();
}
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> clazzes = new HashSet<Class<?>>();
clazzes.add(CoffeePriceService.class);
clazzes.add(JacksonFeature.class);
clazzes.add(OAuth2FilterFeature.class);
return clazzes;
}
}
JerseyOAuth2
DEMO
Authorization Server
● Web Application based on Guice / Dependency Injection
 (Almost) everything is a service:
 UserService, TokenService, ClientService, etc.
 Use default or implement your own!
● Identity Provider:
 Built-in (e.g. Container)
 External (e.g. Lenovo ID)
● Contains user interface for approval/denial of
permissions (bring your own UI technology)
● Implements the authorization and token endpoint
Now It’s Your Turn...
Go enable your Jersey services:
● Maven:
○ <groupId> com.github.hburgmeier.jerseyoauth2 </groupId>
<artifactId> jersey-oauth2 </artifactId>
<version> 0.7 </version>
● GitHub:
○ https://github.com/hburgmeier/jerseyoauth2
● Sample Code:
○ https://github.com/hburgmeier/JavaOne2013
● Fork me!
Questions?
We are hiring in
Freiburg, Germany!
matthias.miltz@haufe-lexware.com
We are hiring in
Morrisville, NC!
hburgmeier@lenovo.com
Image Credits
Slide 2: By McKay Savage from London, UK [CC-BY-2.0], via Wikimedia Commons
Slide 4: By Hubert DENIES (Own work) [CC-BY-SA-3.0], via Wikimedia Commons
Slide 5: By Kweniston (Own work) [CC-BY-3.0], via Wikimedia Commons
Slide 6: By Ibonzer (Own work) [CC-BY-SA-3.0], via Wikimedia Commons
Slide 7: 2004 by Tomasz Sienicki [CC BY 2.5]
Slide 8: by Joe Shlabotnik [CC-BY 2.0] via Flickr
Slide 9: By Demilune [CC-BY-SA-2.5], via Wikimedia Commons
Slide 10: By David Bacon (Flickr: IMG_5126) [CC-BY-2.0], via Wikimedia
Commons
Slide 11: By Andrés Nieto Porras from Palma de Mallorca, España ([C] Café
Uploaded by russavia) [CC-BY-SA-2.0], via Wikimedia Commons
Slide 15: By Scott Schiller (Flickr: Master lock, "r00t" password) [CC-BY-2.0], via
Wikimedia Commons
Slide 16:
https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png

Mixing OAuth 2.0, Jersey and Guice to Build an Ecosystem of Apps - JavaOne 2013

  • 1.
    Mixing OAuth 2.0, Jerseyand Guice to Build an Ecosystem of Apps Hermann Burgmeier Matthias Miltz JavaOne September 2013
  • 2.
    Building an Ecosystem ●Co-Innovation with the community  Mobile platform support  SaaS model (Chaining of services) ● Provide (REST-)API for your service ● Ease of consumption for 3rd party developers ○ Many OAuth2 client libraries available ● Don’t worry about things that don’t deliver value: ○ Authentication ○ Authorization
  • 3.
    Password Anti-Pattern ● Shareyour user/password directly o Can you trust the site? o Do you know if they store it? o How to revoke access? ● Users get careless about sharing their password ● No authorization of the requesting site ● No fine grained permissions ● Changing the password frequently cuts off all sites
  • 4.
    OAuth 2.0 ● Protocolfor authorization - not authentication ● Delegated model o Fix the password anti-pattern! o Trust relationship between resource, identity server and client app ● Official IETF standard since Oct-2012 (http://oauth.net/2/) ● Goal was simplicity: o Nounces / Signing of requests, anyone? o No verification code ● Relies heavily on TLS/SSL
  • 5.
    OAuth 2.0 -Implementations ● Early implementations by Google, Facebook, Github, etc. ● Java Open Source Server Implementations: ○ OAuth for Spring ○ Apis Authorization Server ○ Apache Oltu ○ Apache CXF ○ Restlet Framework ○ Jersey-OAuth2 ■ Available on Github (github/hburgmeier/jerseyoauth2) ■ Based on dependency injection (Guice) ■ Variants for Jersey 1.x and 2.x ■ MIT License
  • 6.
    OAuth 2 –Supported Flows ● Authorization Code ○ Strong authentication of the client ○ Trade authorization code for token ● Implicit ○ For clients that can’t keep a secret ● Resource Owner Password Credentials ○ If you and your users trust the client app... ● Client Credentials ○ To replace the common API key / API secret pattern ○ Used by Twitter
  • 7.
    OAuth 2 forMobile Native Apps ● Mobile applications can’t really keep a client secret ● Only two possible flows: o Authorization Code  No client secret possible o Implicit Grant  No refresh token  Based on “phony” Redirect-URL ● Standard proposes use of an internal/external browser
  • 8.
    Our Demo ● Serviceto provide last coffee bean price  REST service returning JSON object  Implemented using JAX-RS 2.0 and Jersey 2.0 ● What we want to do:  Enable OAuth 2.0 on the service  Javascript-based client as pure HTML application • OAuth 2 Implicit Grant  Integrate external identity provider (Lenovo ID)  Hosted on OpenShift
  • 9.
    Protocol Flow ImplicitGrant HTTP/1.1 302 Found Location: http://client.example.com/cb# access_token=mF_9.B5f-4.1JqM& expires_in=3600 GET /authorize? response_type=token& client_id=jsOnlyClientID& redirect_uri=https://client.example.com/cb GET /resource/1 Authorization: Bearer mF_9.B5f-4.1JqM
  • 10.
    Implementing Implicit Grantin JavaScript ● Can’t keep a OAuth secret because JavaScript is visible/debuggable in the browser ● Redirect URI is used for client authentication ● Access Token is transported as URL fragment ● Cross domain HTTP request to access REST service o Only works in modern browsers o Requires a CORS enabled resource server
  • 11.
    How to EnableYour Service @Path("/coffee") public class CoffeePriceService { @GET @Produces({ MediaType.APPLICATION_JSON }) public CoffeePrice get() { … }
  • 12.
    How to EnableYour Service @OAuth20 @AllowedScopes(scopes = {"espresso"}) @Path("/coffee") public class CoffeePriceService { @GET @Produces({ MediaType.APPLICATION_JSON }) public CoffeePrice get() { … }
  • 13.
    JAX-RS / Jersey2.0 in our Example public class RestApplication extends Application { @Inject public RestApplication(ServiceLocator serviceLocator) { DynamicConfiguration dc = Injections.getConfiguration(serviceLocator); Injections.addBinding(Injections.newBinder(DefaultConfiguration.class).to(IRSConfiguration.class), dc); Injections.addBinding(Injections.newBinder(AccessTokenVerifier.class).to(IAccessTokenVerifier.class), dc); Injections.addBinding(Injections.newBinder(RequestFactory.class).to(IRequestFactory.class), dc); dc.commit(); } @Override public Set<Class<?>> getClasses() { Set<Class<?>> clazzes = new HashSet<Class<?>>(); clazzes.add(CoffeePriceService.class); clazzes.add(JacksonFeature.class); clazzes.add(OAuth2FilterFeature.class); return clazzes; } }
  • 14.
  • 15.
    Authorization Server ● WebApplication based on Guice / Dependency Injection  (Almost) everything is a service:  UserService, TokenService, ClientService, etc.  Use default or implement your own! ● Identity Provider:  Built-in (e.g. Container)  External (e.g. Lenovo ID) ● Contains user interface for approval/denial of permissions (bring your own UI technology) ● Implements the authorization and token endpoint
  • 16.
    Now It’s YourTurn... Go enable your Jersey services: ● Maven: ○ <groupId> com.github.hburgmeier.jerseyoauth2 </groupId> <artifactId> jersey-oauth2 </artifactId> <version> 0.7 </version> ● GitHub: ○ https://github.com/hburgmeier/jerseyoauth2 ● Sample Code: ○ https://github.com/hburgmeier/JavaOne2013 ● Fork me!
  • 17.
    Questions? We are hiringin Freiburg, Germany! matthias.miltz@haufe-lexware.com We are hiring in Morrisville, NC! hburgmeier@lenovo.com
  • 18.
    Image Credits Slide 2:By McKay Savage from London, UK [CC-BY-2.0], via Wikimedia Commons Slide 4: By Hubert DENIES (Own work) [CC-BY-SA-3.0], via Wikimedia Commons Slide 5: By Kweniston (Own work) [CC-BY-3.0], via Wikimedia Commons Slide 6: By Ibonzer (Own work) [CC-BY-SA-3.0], via Wikimedia Commons Slide 7: 2004 by Tomasz Sienicki [CC BY 2.5] Slide 8: by Joe Shlabotnik [CC-BY 2.0] via Flickr Slide 9: By Demilune [CC-BY-SA-2.5], via Wikimedia Commons Slide 10: By David Bacon (Flickr: IMG_5126) [CC-BY-2.0], via Wikimedia Commons Slide 11: By Andrés Nieto Porras from Palma de Mallorca, España ([C] Café Uploaded by russavia) [CC-BY-SA-2.0], via Wikimedia Commons Slide 15: By Scott Schiller (Flickr: Master lock, "r00t" password) [CC-BY-2.0], via Wikimedia Commons Slide 16: https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png