Reader small image

You're reading from  Modern API Development with Spring 6 and Spring Boot 3 - Second Edition

Product typeBook
Published inSep 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781804613276
Edition2nd Edition
Languages
Concepts
Right arrow
Author (1)
Sourabh Sharma
Sourabh Sharma
author image
Sourabh Sharma

Sourabh Sharma is a Senior Development Manager at Oracle with over 20 years of experience in the industry. He is a manager and architect who has been designing on-premise and cloud-based applications using Java, Javascript, and Oracle DB. Sourabh has worked with leading companies and delivered enterprise products and applications. His expertise lies in conceptualizing, modeling, designing, and developing N-tier and cloud-based web applications while leading teams. Sourabh's experience also includes developing microservice-based solutions and implementing various types of workflow and orchestration engines. He believes in continuous learning and sharing knowledge through his books and training.
Read more about Sourabh Sharma

Right arrow

Securing REST Endpoints Using Authorization and Authentication

In previous chapters, we developed a RESTful web service using imperative and reactive coding styles. Now, you’ll learn how you can secure these REST endpoints using Spring Security. You’ll implement token-based authentication and authorization for REST endpoints. A successful authentication provides two types of tokens – a JavaScript Object Notation (JSON) Web Token (JWT) as an access token, and a refresh token in response. This JWT-based access token is then used to access the secured Uniform Resource Locators (URLs). A refresh token is used to request a new JWT if the existing JWT has expired, and a valid request token provides a new JWT to use.

You’ll associate users with roles such as admin and user. These roles will be used as authorization to make sure that REST endpoints can only be accessed if a user holds certain roles. We’ll also briefly discuss cross-site request forgery...

Implementing authentication using Spring Security 
and JWT

Spring Security is a framework consisting of a collection of libraries that allow you to implement enterprise application security without worrying about writing boilerplate code. In this chapter, we will use the Spring Security framework to implement token-based (JWT) authentication and authorization. Throughout the course of this chapter, you will also learn about CORS and CSRF configuration.

It’s useful to know that Spring Security also provides support for opaque tokens, just like it does for JWTs. The main difference between them is how information is read from the token. You can’t read the information from an opaque token the way you can with a JWT – only the issuer is aware of how to do this.

Note

A token is a string of characters such as

5rm1tc1obfshrm2354lu9dlt5reqm1ddjchqh81 7rbk37q95b768bib0j
f44df6suk1638sf78cef7 hfolg4ap3bkighbnk7inr68ke780744fpej0gtd 9qflm999o8q...

Securing REST APIs with JWT

In this section, you’ll secure the REST endpoints exposed in Chapter 4, Writing Business Logic for APIs. Therefore, we’ll use the code from Chapter 4 and enhance it to secure the APIs.

The REST APIs should be protected using the following techniques:

  • No secure API should be accessed without a JWT.
  • A JWT can be generated using sign-in/sign-up or a refresh token.
  • A JWT and a refresh token should only be provided for a valid user’s username/password combination or a valid user sign-up.
  • The password should be stored in an encoded format using a bcrypt strong hashing function.
  • The JWT should be signed with Rivest-Shamir-Adleman (RSA) keys with a strong algorithm.

RSA

RSA is an algorithm approved by the Federal Information Processing Standards (FIPS) (FIPS 186) for digital signatures and in Special Publication (SP) (SP800-56B) for key establishment.

  • Claims in the payload should not store sensitive...

Configuring CORS and CSRF

Browsers restrict cross-origin requests from scripts for security reasons. For example, a call from http://mydomain.com to http://mydomain-2.com can’t be made using a script. Also, an origin not only indicates a domain but also includes a scheme and a port.

Before hitting any endpoint, the browser sends a pre-flight request using the HTTP method option to check whether the server will permit the actual request. This request contains the following headers:

  • The actual request’s headers (Access-Control-Request-Headers).
  • A header containing the actual request’s HTTP method (Access-Control- Request-Method).
  • An Origin header that contains the requesting origin (scheme, domain, and port).
  • If the response from the server is successful, then only the browser allows the actual request to fire. The server responds with other headers, such as Access- Control-Allow-Origin, which contains the allowed origins (an asterisk * value...

Understanding authorization

Your valid username/password or access token for authentication gives you access to secure resources, such as URLs, web resources, or secure web pages. Authorization is one step ahead; it allows you to configure access security further with scopes such as read, write, or roles such as Admin, User, and Manager. Spring Security allows you to configure any custom authority.

We will configure three types of roles for our sample e-commerce app – namely, Customer (user), Admin, and Customer Support Representative (CSR). Obviously, each user will have their own specific authority. For example, a user can place an order and buy stuff online but should not be able to access the CSR or admin resources. Similarly, a CSR should not be able to have access to admin-only resources. A security configuration that allows authority or role-based access to resources is known as authorization. A failed authentication should return an HTTP 401 status (unauthorized)...

Testing security

By now, you must be looking forward to testing. You can find the API client collection at the following location. You can import it and then test the APIs, using any API client that supports the HAR type file import: https://github.com/PacktPublishing/Modern-API-Development-with-Spring-6-and-Spring-Boot-3/blob/main/Chapter06/Chapter06-API-Collection.har.

Important note

Make sure to generate the keys again, as keys generated by the JDK keytool are only valid for 90 days.

Building and running the Chapter 06 code

You can build the code by running gradlew clean build from the root of the project, and you can run the service using java -jar build/libs/Chapter06-0.0.1-SNAPSHOT.jar. Make sure to use Java 17 in the path.

Now, let’s test our first use case.

Let’s fire the GET /api/vi/addresses API without the Authorization header, as shown in the following command:

$ curl -v 'http://localhost:8080/api/v1/addresses' -H 'Content...

Summary

In this chapter, you learned about JWTs, Spring Security, authentication using filters, and JWT token validation, using filters and authentication with the Spring OAuth 2.0 resource server. You also learned how you can add CORS and CSRF protection and why these are necessary.

You also learned about access protection based on roles and authorities. You have now the skills to implement JWTs, Spring Security, and the Spring Security OAuth 2.0 resource server to protect your web resources.

In the next chapter, you will develop a sample e-commerce app’s UI using the Spring Security framework and APIs used in this chapter. This integration will allow you to understand the UI flows and how to consume REST APIs using JavaScript.

Questions

  1. What is a security context and a principal?
  2. Which is the preferred way to secure a JWT – signing or encrypting a token?
  3. What are the best practices to use a JWT?

Answers

  1. The security context stores the principal using SecurityContextHolder and is always available in the same thread of execution. The security context allows you to extract the principal during the flow execution and use it wherever you want. This is where a security annotation such as @PreAuthorize makes use of it for validation. The principal is the currently logged-in user. It can either be an instance of UserDetails or a string carrying a username. You can use the following code to extract it:
    Object principal = SecurityContextHolder                   .getContext().getAuthentication()                   .getPrincipal();if (principal instanceof UserDetails) {  String username =              ((UserDetails)principal...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Modern API Development with Spring 6 and Spring Boot 3 - Second Edition
Published in: Sep 2023Publisher: PacktISBN-13: 9781804613276
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Sourabh Sharma

Sourabh Sharma is a Senior Development Manager at Oracle with over 20 years of experience in the industry. He is a manager and architect who has been designing on-premise and cloud-based applications using Java, Javascript, and Oracle DB. Sourabh has worked with leading companies and delivered enterprise products and applications. His expertise lies in conceptualizing, modeling, designing, and developing N-tier and cloud-based web applications while leading teams. Sourabh's experience also includes developing microservice-based solutions and implementing various types of workflow and orchestration engines. He believes in continuous learning and sharing knowledge through his books and training.
Read more about Sourabh Sharma