Spring Security JWT

Quick and easy support for inter-microservice request authentication using JSON Web Tokens with Spring Security.

License

License

Categories

Categories

Ant Build Tools Security
GroupId

GroupId

com.github.grantjforrester
ArtifactId

ArtifactId

spring-security-jwt
Last Version

Last Version

1.0
Release Date

Release Date

Type

Type

jar
Description

Description

Spring Security JWT
Quick and easy support for inter-microservice request authentication using JSON Web Tokens with Spring Security.
Project URL

Project URL

https://github.com/grantjforrester/spring-security-jwt
Source Code Management

Source Code Management

https://github.com/grantjforrester/spring-security-jwt

Download spring-security-jwt

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.grantjforrester/spring-security-jwt/ -->
<dependency>
    <groupId>com.github.grantjforrester</groupId>
    <artifactId>spring-security-jwt</artifactId>
    <version>1.0</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.grantjforrester/spring-security-jwt/
implementation 'com.github.grantjforrester:spring-security-jwt:1.0'
// https://jarcasting.com/artifacts/com.github.grantjforrester/spring-security-jwt/
implementation ("com.github.grantjforrester:spring-security-jwt:1.0")
'com.github.grantjforrester:spring-security-jwt:jar:1.0'
<dependency org="com.github.grantjforrester" name="spring-security-jwt" rev="1.0">
  <artifact name="spring-security-jwt" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.grantjforrester', module='spring-security-jwt', version='1.0')
)
libraryDependencies += "com.github.grantjforrester" % "spring-security-jwt" % "1.0"
[com.github.grantjforrester/spring-security-jwt "1.0"]

Dependencies

compile (4)

Group / Artifact Type Version
org.springframework.security : spring-security-web jar 4.2.10.RELEASE
org.slf4j : slf4j-api jar 1.7.25
com.nimbusds : nimbus-jose-jwt jar 6.4.2
org.slf4j : jcl-over-slf4j jar 1.7.25

provided (1)

Group / Artifact Type Version
javax.servlet : javax.servlet-api jar 3.0.1

test (7)

Group / Artifact Type Version
org.springframework : spring-test jar 4.3.21.RELEASE
org.slf4j : slf4j-simple jar 1.7.25
org.junit.jupiter : junit-jupiter-engine jar 5.1.0
org.hamcrest : hamcrest-library jar 1.3
com.github.npathai : hamcrest-optional jar 2.0.0
eu.codearte.catch-exception : catch-exception jar 2.0
org.mockito : mockito-core jar 2.23.4

Project Modules

There are no modules declared in this project.

spring-security-jwt

Travis (.org) Codecov

A lightweight module for Spring Security that provides HTTP request authentication by JSON Web Token (JWT).

When configured all incoming requests to the Spring application are intercepted and must have a valid JWT to be authenticated, otherwise a response with status code 401 is returned.

A JWT is valid if:

  • it is well-formed
  • any "nbf" claim has elapsed
  • any "exp" claim has not elapsed
  • has the correct signature based on a provided key.

The Spring Security Context

On successful authentication the JWTAuthenticationManager builds a PreAuthenticatedAuthenticationToken which is set in the current Spring SecurityContext.

The token is populated from the JWT as follows:

  • claim sub is set as the principal
  • claim roles (an array of strings) is set as the collection of authorities
  • the JWT itself is set as the credentials

If you want to use Spring's method security then I recommend each string in your roles claim has the prefix ROLE_.

Example

{
   ...,
   "roles" : ["ROLE_AddUser", "ROLE_DeleteUser"],
   ...
}

JWT Signature Checking

To verify a JWT signature a key must be provided. Two methods of providing a key are supported:

From Shared Secret

The key is built from a shared secret usually passed in as a configuration value. See class FromSharedSecret.

From KeySet By Kid Claim

Each JWT must specify a "kid" claim in the header. This value is used to locate a key in the configured JWKS key set. See class FromKeySetByKidClaim.

Usage

In your Spring application configure Spring Security as follows:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${keystore.filename}")
    private Resource keystore;

    @Autowired
    private ApplicationContext context;

    /*
     * Create an authentication filter that looks for a JWT in an "Authorization" header with 
     * the authentication scheme "Bearer".  Use the given JWTAuthenticationManager to 
     * authenticate the JWT.
     */
    @Bean
    Filter authenticationFilter(JWTAuthenticationManager jwtAuthenticationManager) {
        JWTAuthenticationFilter filter = new JWTAuthenticationFilter();
        filter.setJwtProvider(new HeaderJWTProvider("Authorization", "Bearer"));
        filter.setAuthenticationManager(jwtAuthenticationManager);
        filter.setAuthenticationDetailsSource(new WebAuthenticationDetailsSource());
        return filter;
    }

    /*
     * Create a JWTAuthenticationManager bean responsible for verifying the JWT and setting
     * up the SecurityContext.
     */
    @Bean
    JWTAuthenticationManager jwtAuthenticationManager() throws Exception {
        FromKeySetByKidClaim keySelector = new FromKeySetByKidClaim(JWKSet.load(keystore.getInputStream()));
        return new NimbusJWTAuthenticationManager(keySelector);
    }

    /*
     * Intercept incoming requests with the JWTAuthenticationFilter. If authentication fails
     * return response with status code 401.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        Filter authenticationFilter = (Filter) context.getBean("authenticationFilter");
        http.addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class)
            .authorizeRequests().anyRequest().authenticated()
            .and().sessionManagement().sessionCreationPolicy(STATELESS)
            .and().exceptionHandling().authenticationEntryPoint(
                new StatusCode401AuthenticationEntrypoint()
            );
    }
}

Versions

Version
1.0