Oath2.0 cookbook-use Spring Security to protect your web applications

Foreword

OAuth 2.0 is a standard protocol for authorization. It focuses on simplifying the work of client developers, while providing a specific authorization process for Web applications, desktop applications, mobile phones, etc. Given the documentation available for the OAuth specification, you might think it is complicated. However, this book promises to help you get started with OAuth 2.0 through examples in simple recipes. It focuses on providing specific authorization flows for various applications through interesting recipes. It also provides useful recipes that can be used to solve actual problems and create Android applications using Spring Security

What this book covers

Chapter 1, OAuth 2.0 Basics, contains recipes that will cover the basics of OAuth 2.0 with simple recipes that allow readers to work with public APIs protected by OAuth 2.0 (such as Facebook, LinkedIn, and Google) Interaction.

Chapter 2, Implementing Your OAuth 2.0 Provider, introduces how to implement your own OAuth 2.0 provider, and introduces ways to help Authorization Server and Resource Server configuration considering different OAuth 2.0 grant types. It also explains how to use different database storage access tokens to effectively use refresh tokens.

Chapter 3, Using OAuth 2.0 Protected APIs, introduces recipes that help create OAuth 2.0 client applications that can interact with all authorization types described in the OAuth 2.0 specification. It also explains how to manage refresh tokens on the client.

Chapter 4, OAuth 2.0 configuration files, introduces some OAuth 2.0 configuration files and how to implement them using Spring Security OAuth2. These profiles are specified to help solve specific situations not covered by the OAuth 2.0 specification, such as token revocation and token introspection that allows remote authentication. This recipe also provides some suggestions, such as how and when to use the cache when using remote authentication.

Chapter 5, using JWT's self-contained tokens, focuses on how to use JWT as an OAuth 2.0 access token and how to implement the main extensions of JWT, such as JWS and JWE, providing signatures and encryption to protect what JWT access tokens convey content. This chapter also provides a good way to improve the security of the application by using Ownership Proof Semantics on OAuth 2.0.

Chapter 6, OpenID Connect for authentication, introduces the difference between authorization and authentication, and how OAuth 2.0 helps build authentication protocols. To illustrate the use of OpenID Connect, all the recipes introduced in this chapter are aimed at client applications, rather than building OpenID Connect providers.

Chapter 7, Implementing Mobile Clients, describes how to use Android as a recipe platform to implement OAuth 2.0 native mobile clients. This chapter introduces some guidelines specified by the recently released specification called OAuth 2.0 for native applications.

Chapter 8, Avoiding Common Vulnerabilities, covers ways to better protect the main components considered in the OAuth 2.0 ecosystem.

Chapter 1: OAuth 2.0 basics

This chapter covers the following recipe:
Prepare the environment
to read the user's contacts from Facebook in the client's
read the user's contacts from Facebook on the server side
access OAuth 2.0 LinkedIn protected resource
access user session is bound to OAuth 2.0 Google Protected Resources

Introduction

The main purpose of this chapter is to help you integrate with popular web applications and social media, while at the same time familiarizing you with the basic principles of the OAuth 2.0 specification.

Before delving into recipes for several use cases, let's take a look at the overview of most scenarios that will be covered. This will give you the opportunity to review some important concepts about the OAuth 2.0 specification, so we can be consistent with the terminology used throughout this book.

Resource owner-> Mobile client ---> Identity provider
| ----> Resource server
| ----------------> oauth 2.0 avoider --- |- > Authorization server ----> Relational database redis
| |-> |-> Resource server
| |
| ---> Web client ---> Third party application

The figure above shows the four main components of the OAuth 2.0 specification:

Resource owner
Authorization server
Resource server
Client

Just to see the purpose of these components, remember that the resource owner is the user who delegates permission to use resources on behalf of third-party applications. The third-party application mentioned is represented by the client, and I describe it as a mobile client and a web client. The user's resources are usually maintained and protected by the resource server. For example, the resource server can be implemented as a single component together with the authorization server. The composition of the authorization server and the resource server is called an OAuth 2.0 provider to simplify the terminology given to applications protected by OAuth 2.0.

Prepare the environment


Since most of the examples are written in Java, we will also need an integrated development environment (IDE) and a good framework to help us write simple web applications (because the OAuth 2.0 protocol is designed for HTTP use) , It will be Spring. To simplify the use of Spring-related technologies, this recipe will help you prepare your application using Spring Boot, and provide sample endpoints and how to use Maven to run the project.

be prepared


As mentioned earlier, we will use the Spring Boot Framework to run most recipes, which simplifies the development of Spring Framework-based applications. Therefore, to run this recipe, you only need an environment that can download some files from the Internet and configure Java 8 and the CURL tool correctly on your computer.

CURL is a tool that allows you to run HTTP requests through the command line. In Linux and Mac OS environments, it is available by default, so if you want to run the recipe on Windows, you should install it first. You can download the tool from https://curl.haxx.se/download.html and install it. You just need to unzip and add the path of the binary file to the PATH environment variable of Windows.

How to do it:

The following steps describe how to prepare the environment and how to generate a simple project from the Spring Initializr website, which will be executed using the appropriate Maven commands:

Generate a project using the Spring Initializr service by visiting // https: //start.spring.io/. Spring Initializr provides many options to start setting up a project. For example, if you want to use Maven or Gradle to manage project dependencies, which version of Spring Boot to use, which dependencies to use, and even change the language from Java to Groovy or Kotlin.

For this simple test, you only need to use the Java language and the default value of the Spring Boot version 1.5.7 project manager Maven Project.

In Project Metadata, change the value of the Group field to com.packt.example.

Still on the project metadata, change the artifact name to simplemvc.

In the "Dependencies" section, type web and select "Use Tomcat and Spring MVC for full-stack web development." After selecting the correct option, you will see the "Web" tab under "Selected Dependencies" as shown below:

After setting all the requirements for this simple example, click the "Generate Project" button and your browser will start downloading the ZIP file to your "Download" folder.

After downloading the file, you can unzip it and import it into the IDE to browse the structure of the created project. For Eclipse users, simply import the project as a Maven project.

Open the class SimplemvcApplication, you will see the following code in the IDE:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wangjunji</groupId>
	<artifactId>auth20</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>auth20</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Code

package com.wangjunji.auth20;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
@SpringBootApplication
public class Auth20Application {

	@GetMapping("/message")
	public ResponseEntity<String> getMessage(){
		return ResponseEntity.ok("hello");
	}
	public static void main(String[] args) {
		SpringApplication.run(Auth20Application.class, args);
	}

}

The OAuth 2.0 specification is available through RFC 6749 at: https: / / tools. Ietf.org/ html / rfc6749
You can read more about Spring Boot below: https: / / docs. Spring.io/ spring- / boot / docs / current / reference / htmlsingle
how this works ...
Because of the use of Spring Boot, we can use projects such as Spring MVC and Spring Security. These Spring projects can help us write Web applications, REST APIs, and help us protect application security. For example, by using the Spring Security OAuth2 project, we can additionally configure our own OAuth 2.0 provider to work like a client. This is important because people who try to write their own OAuth Provider will have to deal with too many details, which can easily make the OAuth Provider insecure. Spring Security OAuth2 has solved the main problem that any developer must consider.

In addition, Spring Boot simplifies the initial steps of application boot. When creating a Spring project without Spring Boot, we need to manually handle dependencies by taking care of possible library conflicts. To solve this problem, Spring Boot provides some pre-configured modules provided by the startup program. As a useful introductory example, let us consider an application with Spring Data JPA. Instead of declaring all dependencies of hibernate, entity-manager, and transaction-api, just declare spring-boot -starterdata-jpa to automatically import all dependencies.

When you start using Spring Boot, by using the Spring Initializr service provided by Pivotal (now a Spring maintainer), things will become easier.

There is more ...
all examples presented in Java can be imported and executed with any Java IDE, but we will use Eclipse because it is a large tool approved by developers around the world. Although this book describes how to use Eclipse, you can stick to your preferred tool if needed. Today, many projects are designed using Gradle, but many developers are still used to creating projects with Maven to manage dependencies and the project itself. Therefore, in order to avoid skill errors or any other types of problems with the IDE plug-in, the recipe using Spring Boot will be managed by Maven. In addition, the Eclipse IDE already comes with a Maven plug-in, which was not applicable to Gradle at the time of writing this book. To use Gradle to run a project in Eclipse, a specific plug-in must be installed.

You can also take a look at
Spring Boot provides many entry tools that can help you use a large number of tools and libraries to develop applications. If you want to search more, please go to http: / / docs. Spring. Io / spring- boot / docs / 1. 5. 7. RELEASE / reference / htmlsingle / # Using- boot- starter

Read the user's contacts from the client's Facebook

This recipe will show you how to use implicit grant types to integrate with Facebook, which is a better choice for public clients and can be run directly on the user's web browser.

As you may already know, the grant type defines different methods for applications to retrieve access tokens from the authorization server. The authorization type can be applied to a given scheme related to the type of client being developed. As a reminder, the OAuth 2.0 specification defines two types of client types: public and confidential.

Get ready
To run this recipe, you must use Spring Boot to create a web application, which will help the application development. In addition, we also need to register our application on Facebook. This is an important step in using OAuth 2.0, because as an OAuth provider,
Facebook needs to know which clients are requesting access tokens, and the resource owner (user) of course wants to know who wants to grant access to their profile

How to do it ...
Please follow these steps to create a client application to integrate with Facebook using the client process in OAuth 2.0:

First, remember that you must have a Facebook account and must register a new application. Go to https://developers.facebook.com/apps/, you should see something similar to the following:

Click "Create New Application" to start registering your application, and then you will see the following interface, which can be used to define the name of the application:

Click Create Application ID and you will be redirected to the dashboard of the newly created application as shown below:

To start using Facebook's Graph API and retrieve the user's contacts, we first need to select a product from the multiple products provided by Facebook. For what we need now, you must click the "Settings" button in the Facebook login box.

After clicking "Settings", you must select a platform, which must be Web.

After selecting the web platform, enter the site URL of your application. I am using a file called http: //clientimplicit.test

After saving the website URL, just click continue

Now you can set the redirect URI of the application by clicking "Settings" in the left panel as shown below. Since the application is not yet in production, I set the redirect URI to http: // localhost: 8080 / callback. Do n’t forget to save your changes:

Now you can click on the dashboard on the left side of the panel to get the App ID and App Secret, which correspond to the client_id and client_secret of the OAuth 2.0 specification, respectively.

Copy the App ID and App Secret from the dashboard, as shown in the following screenshot, as shown below, so we can use the following code in subsequent steps:

Once we have registered the customer on Facebook, we can start writing code to retrieve the OAuth 2.0 access token (request the access token from the client) using the implicit grant type.

Use Spring Initializr to create a new web application at the following location https://start.spring.io/ and define the following data:
  set the group to com.packt.example
to define the artifact as a client implicitly
add Web and Thymeleaf Dependencies for the project

 

Create the file client.html in the folder template inside the src / main / resources project directory

Add content client.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:charset="UTF-8">
<head>
    <meta charset="UTF-8">
    <title>CLIENT</title>
</head>
<body>
Press the following button to start the implicit flow.
<button id="authorize" type="button">Authorize</button>
<div id="box"></div>
</body>
</html>

The button we added to the client.html page has no behavior. Therefore, to allow users to start the implicit grant type process, add the following JavaScript code after the body tag:

Before starting the application, we need to map a URL pattern so that the HTML code written before can be rendered. To do this, open the class ClientImplicitApplication.java and ensure that your code looks like this:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
@SpringBootApplication
public class ClientApplication {
	@GetMapping("/")
	public String client(){
		return "client";
	}

	public static void main(String[] args) {
		SpringApplication.run(ClientApplication.class, args);
	}

}

In the previous code, we have mapped the application's root directory to the client.html web page. However, all this is now to send the authorization server (Facebook in this case) to the user so that she can grant our application access to the protected resource (her friend). Try to start the application, then go to http: // localhost: 8080 /

Click on the client.html that will be provided; the Authorize button to start the Implicit grant process, log in with your Facebook account, and accept the permissions requested by the client ’s implicit application (make sure the jquery.html file is properly declared in the client) .

If you grant all permissions on the consent user page, you should be redirected to the http: // localhost: 8080 / callback URL specified during Facebook ’s client registration phase. Click Continue, and pay attention to the received content and the URL fragment in the browser address bar. It should be similar to the following:

http://localhost:8080/callback#access_token=EAAbsiSHMZC60BANUwKBDCYeySZCjcBpvFuUO1gXsfTGwWjnZAFTAZBIJB62jdUroAcNuZAVWO24yeqo0iazWYytVgrQ1bgNWI8vm07Ws4ZCHXpGridHfZB6PQ1rzM4BzP29IljgTTuBLZBFQBEnEn2LJiOWJjA8J6Y73BLcjIe2vVMZB9c2GnZBpiK4iZAWEtkTsMEZD&expires_in=7152

Now, we need to extract the access_token and expires_in parameters after #character and start using the Facebook Graph API to retrieve the user's friends.

The first thing we need to do is to create another URL mapping through our default controller ClientImplicitApplication. Open this class and add the following method so that we can handle Facebook redirects:

@GetMapping("/callback")
public String callback() { return "callback_page"; }

As we can see, the callback method returns the callback_page string, which will be automatically mapped to the file callback_page.html. So let's create this file in the templates folder in the src / main / resources project directory. First, just add the following HTML content to the callback_page.html file:

<!DOCTYPE html>
<html>
<head><title>Insert title here</title></head>
<body>
Friends who has also granted client-implicit
<div id="friends">
<ul></ul>
</div>
</body>
</html>

After receiving acces_token as a URL fragment, the file will use JavaScript code to interact with Facebook's graph API to retrieve the user's friends, and will populate the tag <ul> with each friend received in the <li> tag. Let's start writing JavaScript code by adding the following content after the body tag

<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.
js"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
var fragment = window.location.hash;
});
/*]]>*/
</script>

Since the fragment variable contains the content of the fragment, add the following function at the end of the JavaScript code:

function getResponse(fragment) {
var attributes = fragment.slice(1).split('&');
var response = {};
$(attributes).each(function(idx, attr) {
var keyValue = attr.split('=');
response[keyValue[0]] = keyValue[1];
});
response.hasError = function() {
return !response['access_token'];
};
return response;
}

The code provided above creates an object called response, which may contain an access_token or error description. Unfortunately, Facebook returns all error data as URL query parameters, instead of using fragments according to the OAuth 2.0 specification. At least the object returned by the getResponse function can determine whether there is an error in the response.

Now, update the main JavaScript code to the following. The following code extracts the response from the URL fragment as a security measure to clear the URL fragment. If an error occurs, only a message is displayed to the user through the <div> HTML tag:

 

Published 158 original articles · Like 28 · Visit 330,000+

Guess you like

Origin blog.csdn.net/wangjunji34478/article/details/105613733
Recommended