All Projects → dhatim → Dropwizard Jwt Cookie Authentication

dhatim / Dropwizard Jwt Cookie Authentication

Licence: other
Dropwizard bundle managing authentication through JWT cookies

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Dropwizard Jwt Cookie Authentication

Auth Module
auth.nuxtjs.org
Stars: ✭ 1,624 (+5500%)
Mutual labels:  module, cookie, jwt
Rufus
Rufus - fetches the paper for you!
Stars: ✭ 108 (+272.41%)
Mutual labels:  dropwizard, jwt
Pac4j
Security engine for Java (authentication, authorization, multi frameworks): OAuth, CAS, SAML, OpenID Connect, LDAP, JWT...
Stars: ✭ 2,097 (+7131.03%)
Mutual labels:  dropwizard, jwt
Electrode Csrf Jwt
Stateless Cross-Site Request Forgery (CSRF) protection with JWT
Stars: ✭ 127 (+337.93%)
Mutual labels:  cookie, jwt
Silhouette
Silhouette is a framework agnostic authentication library for Scala that supports several authentication methods, including OAuth2, OpenID Connect, Credentials, Basic Authentication or custom authentication schemes.
Stars: ✭ 18 (-37.93%)
Mutual labels:  cookie, jwt
Nginx Cleantalk Service
LUA configuration to filter any POST requests.
Stars: ✭ 13 (-55.17%)
Mutual labels:  module
Nextjs Sequelize
Next.js With Sequelize Web Application, a Full-Stack Web App Development Boilerplate. https://medium.com/@defrian.yarfi/next-js-with-sequelize-web-application-a-full-stack-web-development-a0051074e998
Stars: ✭ 21 (-27.59%)
Mutual labels:  jwt
Apache24 Modules
Modules for Apache 2.4 and maybe 2.2
Stars: ✭ 12 (-58.62%)
Mutual labels:  module
Generator Mage2
Yeoman generator for Magento 2 extensions (modules and themes)
Stars: ✭ 12 (-58.62%)
Mutual labels:  module
Php Storageless Sessions
Sessions handler which stores session data in HMAC-signed and encrypted cookies
Stars: ✭ 29 (+0%)
Mutual labels:  jwt
Peeplus
python+vue3前后端分离项目
Stars: ✭ 28 (-3.45%)
Mutual labels:  jwt
Jose
A JOSE implementation
Stars: ✭ 20 (-31.03%)
Mutual labels:  jwt
Access
Ponzu Addon to manage API access grants and tokens for authentication
Stars: ✭ 13 (-55.17%)
Mutual labels:  jwt
Spring Security Rbac Jwt
springboot2项目的脚手架工程(包含security + jwt方式的动态权限校验)
Stars: ✭ 21 (-27.59%)
Mutual labels:  jwt
Cookie Js
A tiny (1.24 KB gzipped), stand-alone JavaScript utility for managing cookies in the browser.
Stars: ✭ 12 (-58.62%)
Mutual labels:  cookie
Jwt Tornado
An implementation of JSON Web Tokens in Python Tornado
Stars: ✭ 28 (-3.45%)
Mutual labels:  jwt
Dropwizard Hk2bundle
Dropwizard hk2 integration bundle
Stars: ✭ 12 (-58.62%)
Mutual labels:  dropwizard
Ee7 Jaxrs Sample
Building RESTful APIs with Java EE 7 and JAXRS
Stars: ✭ 15 (-48.28%)
Mutual labels:  jwt
Easy Dom
EASYDOM-可能是最适合你的 DOM 课程
Stars: ✭ 21 (-27.59%)
Mutual labels:  cookie
Java9 Jigsaw Depvis
DepVis (Java 9 Jigsaw Dependency Visualizer)
Stars: ✭ 14 (-51.72%)
Mutual labels:  module

Build Status Maven Central Coverage Status Javadoc Mentioned in Awesome Dropwizard

Please note version 4 requires Dropwizard 2.

dropwizard-jwt-cookie-authentication

Statelessness is not only an architectural constaint of RESTful applications, it also comes with a lot of advantages regarding scalability and memory usage.

A common pattern is to provide the client with a signed JWT containing all necessary authorization and/or session state information. This JWT must then be passed along subsequent requests, usually in bearer Authorization HTTP headers.

However, in the particular case where clients of the RESTful application are web applications, it is much more interesting to use cookies. The browser will automatically read, store, send and expire the tokens, saving front-end developers the hassle of doing it themselves.

This dropwizard bundle makes things simple for back-end developpers too. It automatically serializes/deserializes session information into/from JWT cookies.

Enabling the bundle

Add the dropwizard-jwt-cookie-authentication dependency

Add the dropwizard-jwt-cookie-authentication library as a dependency to your pom.xml file:

<dependency>
    <groupId>org.dhatim</groupId>
    <artifactId>dropwizard-jwt-cookie-authentication</artifactId>
    <version>4.2.1</version>
</dependency>

Edit you app's Dropwizard YAML config file

The default values are shown below. If they suit you, this step is optional.

jwtCookieAuth:
  secretSeed: null
  secure: false
  httpOnly: true
  domain: null
  sameSite: null
  sessionExpiryVolatile: PT30m
  sessionExpiryPersistent: P7d

Add the 'JwtCookieAuthConfiguration' to your application configuration class:

This step is also optional if you skipped the previous one.

@Valid
@NotNull
private JwtCookieAuthConfiguration jwtCookieAuth = new JwtCookieAuthConfiguration();

public JwtCookieAuthConfiguration getJwtCookieAuth() {
  return jwtCookieAuth;
}

Add the bundle to the dropwizard application

public void initialize(Bootstrap<MyApplicationConfiguration> bootstrap) {
  bootstrap.addBundle(JwtCookieAuthBundle.getDefault());
}

If you have a custom configuration fot the bundle, specify it like so:

bootstrap.addBundle(JwtCookieAuthBundle.getDefault().withConfigurationSupplier(MyAppConfiguration::getJwtCookieAuth));

Using the bundle

By default, the JWT cookie is serialized from / deserialized in an instance of DefaultJwtCookiePrincipal.

When the user authenticate, you must put an instance of DefaultJwtCookiePrincipal in the security context (which you can inject in your resources using the @Context annotation) using JwtCookiePrincipal.addInContext

JwtCookiePrincipal principal = new DefaultJwtCookiePrincipal(name);
principal.addInContext(context);

Once a principal has been set, it can be retrieved using the @Auth annotation in method signatures. You can also use CurrentPrincipal.get() within the request thread.

Each time an API endpoint is called, a fresh cookie JWT is issued to reset the session TTL. You can use the @DontRefreshSession on methods where this behavior is unwanted.

To specify a max age in the cookie (aka "remember me"), use DefaultJwtCookiePrincipal.setPersistent(true).

It is a stateless auhtentication method, so there is no real way to invalidate a session other than waiting for the JWT to expire. However calling JwtCookiePrincipal.removeFromContext(context) will make browsers discard the cookie by setting the cookie expiration to a past date.

Principal roles can be specified via the DefaultJwtCookiePrincipal.setRoles(...) method. You can then define fine grained access control using annotations such as @RolesAllowed or @PermitAll.

Additional custom data can be stored in the Principal using DefaultJwtCookiePrincipal.getClaims().put(key, value).

Sample application resource

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public DefaultJwtCookiePrincipal login(@Context ContainerRequestContext requestContext, String name){
    DefaultJwtCookiePrincipal principal = new DefaultJwtCookiePrincipal(name);
    principal.addInContext(requestContext);
    return principal;
}

@GET
@Path("logout")
public void logout(@Context ContainerRequestContext requestContext){
    JwtCookiePrincipal.removeFromContext(requestContext);
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public DefaultJwtCookiePrincipal getPrincipal(@Auth DefaultJwtCookiePrincipal principal){
    return principal;
}

@GET
@Path("idempotent")
@Produces(MediaType.APPLICATION_JSON)
@DontRefreshSession
public DefaultJwtCookiePrincipal getSubjectWithoutRefreshingSession(@Auth DefaultJwtCookiePrincipal principal){
    return principal;
}

@GET
@Path("restricted")
@RolesAllowed("admin")
public String getRestrictedResource(){
    return "SuperSecretStuff";
}

Custom principal implementation

If you want to use your own Principal class instead of the DefaultJwtCookiePrincipal, simply implement the interface JwtCookiePrincipal and pass it to the bundle constructor along with functions to serialize it into / deserialize it from JWT claims.

e.g:

bootstrap.addBundle(new JwtCookieAuthBundle<>(MyCustomPrincipal.class, MyCustomPrincipal::toClaims, MyCustomPrincipal::new));

JWT Signing Key

By default, the signing key is randomly generated on application startup. It means that users will have to re-authenticate after each server reboot.

To avoid this, you can specify a secretSeed in the configuration. This seed will be used to generate the signing key, which will therefore be the same at each application startup.

Alternatively you can specify your own key factory:

bootstrap.addBundle(JwtCookieAuthBundle.getDefault().withKeyProvider((configuration, environment) -> {/*return your own key*/}));

Manual Setup

If you need Chained Factories or Multiple Principals and Authenticators, don't register directly the bundle. Use instead its getAuthRequestFilter and getAuthResponseFilter methods to manually setup authentication.

You will also be responsible for generating the signing key and registering RolesAllowedDynamicFeature or DontRefreshSessionFilter if they are needed.

Example:

JwtCookieAuthBundle jwtCookieAuthBundle = new JwtCookieAuthBundle<>(
    MyJwtCookiePrincipal.class,
    MyJwtCookiePrincipal::toClaims,
    MyJwtCookiePrincipal::new);

Key key = JwtCookieAuthBundle.generateKey(configuration.getJwtCookieAuth().getSecretSeed());

environment.jersey().register(
        new PolymorphicAuthDynamicFeature<>(
                ImmutableMap.of(
                        MyJwtCookiePrincipal.class, jwtCookieAuthBundle.getAuthRequestFilter(key),
                        MyBasicPrincipal.class, new BasicCredentialAuthFilter.Builder<MyBasicPrincipal>()
                            .setAuthenticator(new MyBasicAuthenticator())
                            .setRealm("SUPER SECRET STUFF")
                            .buildAuthFilter()
                )
        )
);
environment.jersey().register(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(MyJwtCookiePrincipal.class, MyBasicPrincipal.class)));
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(DontRefreshSessionFilter.class);
environment.jersey().register(jwtCookieAuthBundle.getAuthResponseFilter(key, configuration.getJwtCookieAuth()));

Javadoc

It's here.

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].