Information Security 14 min read

Implementing JWT Authentication with Spring Boot and Angular

This article explains what JSON Web Tokens (JWT) are, describes their structure and security considerations, and provides a complete Spring Boot and Angular example—including Maven configuration, Java filter and controller code, Angular services and UI—to demonstrate how to generate, validate, and use JWTs for authentication and role‑based access control.

Top Architect
Top Architect
Top Architect
Implementing JWT Authentication with Spring Boot and Angular

JWT (JSON Web Token) is a compact, URL‑safe means of representing claims securely between parties; it consists of a header, payload (claims), and signature, and can be signed or encrypted.

The article outlines best practices for securing JWTs, such as always verifying signatures, keeping the secret key confidential, avoiding sensitive data in the payload, and using nonce, expiration, and issued‑at claims to mitigate replay attacks.

For Java developers, the JJWT library (Apache‑licensed) is introduced as a convenient way to create and verify JWTs, supporting all standard JWS algorithms.

Below is a minimal demo project that integrates JWT authentication into a Spring Boot backend and an Angular frontend.

Backend (Spring Boot)

Maven pom.xml configuration:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.nibado.example</groupId>
    <artifactId>jwt-angular-spring</artifactId>
    <version>0.0.2-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <jjwt.version>0.6.0</jjwt.version>
        <spring.boot.version>1.5.3.RELEASE</spring.boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>
    </dependencies>
</project>

JWT filter ( JwtFilter.java ) extracts the Authorization: Bearer <token> header, validates the signature with the secret key, and stores the parsed Claims in the request for downstream handlers.

public class JwtFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            throw new ServletException("Missing or invalid Authorization header.");
        }
        String token = authHeader.substring(7);
        try {
            Claims claims = Jwts.parser().setSigningKey("secretkey")
                    .parseClaimsJws(token).getBody();
            request.setAttribute("claims", claims);
        } catch (SignatureException e) {
            throw new ServletException("Invalid token.");
        }
        chain.doFilter(req, res);
    }
}

The UserController provides a /user/login endpoint that authenticates a hard‑coded user map and returns a signed JWT containing the username and role list.

@RestController
@RequestMapping("/user")
public class UserController {
    private final Map
> userDb = new HashMap<>();
    public UserController() {
        userDb.put("tom", Arrays.asList("user"));
        userDb.put("wen", Arrays.asList("user", "admin"));
    }
    @PostMapping("login")
    public LoginResponse login(@RequestBody UserLogin login) throws ServletException {
        if (login.name == null || !userDb.containsKey(login.name)) {
            throw new ServletException("Invalid login");
        }
        return new LoginResponse(Jwts.builder()
                .setSubject(login.name)
                .claim("roles", userDb.get(login.name))
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, "secretkey")
                .compact());
    }
    // DTO classes omitted for brevity
}

An ApiController demonstrates role‑based access by reading the Claims placed by the filter and checking whether the requested role exists in the token.

@RestController
@RequestMapping("/api")
public class ApiController {
    @GetMapping("role/{role}")
    public Boolean hasRole(@PathVariable String role, HttpServletRequest request) throws ServletException {
        Claims claims = (Claims) request.getAttribute("claims");
        return ((List
) claims.get("roles")).contains(role);
    }
}

Frontend (AngularJS)

The Angular module defines a MainCtrl controller that posts credentials to /user/login , stores the returned token, adds it to the Authorization header, and queries /api/role/{role} to display which roles the user possesses.

var appModule = angular.module('myApp', []);
appModule.controller('MainCtrl', ['mainService', '$scope', '$http', function(mainService, $scope, $http) {
    $scope.login = function() {
        mainService.login($scope.userName).then(function(token) {
            $scope.token = token;
            $http.defaults.headers.common.Authorization = 'Bearer ' + token;
            $scope.checkRoles();
        }, function(error) { $scope.error = error; });
    };
    $scope.checkRoles = function() {
        ['user','admin','foo'].forEach(function(r){
            mainService.hasRole(r).then(function(has){ $scope['role'+r.charAt(0).toUpperCase()+r.slice(1)] = has; });
        });
    };
    // logout, loggedIn, etc.
}]);
appModule.service('mainService', ['$http', function($http) {
    return {
        login: function(username) { return $http.post('/user/login', {name: username}).then(r=>r.data.token); },
        hasRole: function(role) { return $http.get('/api/role/' + role).then(r=>r.data); }
    };
}]);

The accompanying index.html provides a simple UI that shows a login form, success message, and role indicators using Bootstrap styling.

Running the application starts the Spring Boot server, serves the static Angular page, and allows users to log in as tom (user role) or wen (user + admin role), demonstrating JWT generation, transmission, validation, and role‑based authorization.

JavaSpring BootsecurityAuthenticationJWTAngular
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.