# Serving Angular App from Spring Boot Server for Secure 🔐 OAuth Flow

In [the first part](https://hpareek.hashnode.dev/authentication-using-oauth2-openid-connect-in-angular-single-page-application) of the series, we built an angular app that uses OAuth2 for user authentication. In [the fourth part](https://hpareek.hashnode.dev/potential-risks-of-using-oauth2-in-single-page-applications), we discussed some of the limitations of this approach. In this article, we will create a spring boot server that will authenticate the users using OAuth flow and then will serve the angular application. That way we don't need to store any credentials or access tokens in the browser. Thus, this is a more secure method for OAuth flow. Some familiarity with [Spring Boot](https://spring.io/projects/spring-boot) and [Angular](https://angular.io/) is required to follow along with this article. If you are using Windows Operating System, then you should use any shell that allows Unix commands inside Windows ([Git Bash](https://git-scm.com/downloads) for example). Now, let's start coding 👨‍💻

### Serve Angular App using Spring Boot
First, let's try to serve an angular application using the spring boot server. After that, we will add security to it. The following steps are mentioned [here](https://github.com/dsyer/spring-boot-angular) by [Dave Syer](https://github.com/dsyer).

#### Create a Spring Boot Application
First of all, create a spring boot application with `web` dependency. If your IDE has integration to create it, use that or use the following command:
```
curl start.spring.io/starter.tgz -d dependencies=web | tar -zxvf -
./mvnw install
```
Now, we will install `npm` locally in the project in order to install [Angular CLI](https://angular.io/cli).

#### Install NPM Locally
[Frontend Maven Plugin](https://github.com/eirslett/frontend-maven-plugin) lets you install [Node](https://nodejs.org/en/) / [NPM](https://www.npmjs.com/) locally for your project, install dependencies with NPM, and much more. Add this plugin to the project and specify the related commands in the `pom.xml` file.
```
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>

			<!-- Frontend Maven Plugin -->
			<plugin>
				<groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>1.6</version>
                <configuration>
					<!-- Node Version to use -->
                    <nodeVersion>v14.17.6</nodeVersion>
                </configuration>
                <executions>
					<!-- Command to install node and npm locally in the project -->
                    <execution>
                        <id>install-npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                    </execution>
                </executions>
			</plugin>
		</plugins>
	</build>
```
And then run the following command to apply the changes.
```
./mvnw generate-resources
```
For the first time, it will take some time. But later on, this step won't take much time.

#### Install Angular CLI
We use **Angular CLI** to create Angular applications which can be installed using `npm` which we installed in the previous step. Create a file called `npm` with the following content:
```
#!/bin/sh
cd $(dirname $0)
PATH="$PWD/node/":$PATH
node "node/node_modules/npm/bin/npm-cli.js" "$@"
```
And then, run the following command to make the file executable:
```
chmod +x npm
```
This wrapper allows us to use local `node` and `npm` for the app instead of the ones which are installed on the system. Then, run the following command to install the Angular CLI:
```
./npm install @angular/cli
```
Now, create similar wrappers for Angular CLI as well. Create a file called `ng` with the following content:
```
#!/bin/sh
cd $(dirname $0)
PATH="$PWD/node/":"$PWD":$PATH
node_modules/@angular/cli/bin/ng.js "$@"
```
Then, run the following command to make it executable:
```
chmod +x ng
```
To test the wrapper, run the following commands:
```
./ng --version
```
It prints versions of Node and Angular CLI.
#### Create an Angular App
We can either create a new angular app or can pull any existing app. Let's create a new one. We use Angular CLI to create an angular app. Run the following command (inside the spring boot project):
```
./ng new spa
```
This creates a new angular app inside the spring boot project. Follow these steps to move this app to the root:

1. Copy the content of `spa/.gitignore` file and paste it at the bottom of `.gitignore` file.
```
cat spa/.gitignore >> .gitignore
```
2. Delete `spa/node_modules`, `spa/src/favicon.ico`, `spa/.git` and `spa/.gitignore`.
```
rm -rf spa/node* spa/src/favicon.ico spa/.gitignore spa/.git
```
3. Copy everything from `spa` to root and delete `spa`.
```
cp -rf spa/* .
cp spa/.??* .
rm -rf spa
```
4. Specify `target/classes/static` as the output location of `ng build` command in `angula.json` file.
```
sed -i -e 's,dist/spa,target/classes/static,' angular.json
```
#### Building the Project
Add the following execution command in `pom.xml` to install the required packages:
```
<execution>
    <id>npm-install</id>
    <goals>
        <goal>npm</goal>
    </goals>
</execution>
```
Run `./mvnw generate-resources` to install the required packages. Now add the following execution as well to compile the angular app during maven build.
```
    <execution>
        <id>npm-build</id>
        <goals>
            <goal>npm</goal>
        </goals>
        <configuration>
            <arguments>run-script build</arguments>
        </configuration>
    </execution>
```
To stabilize the build, put a `^` before the version of `@angular/cli` in `package.json` file. To build continuously, run `./ng build --watch` command in a separate terminal window and the angular app will be built whenever any related file changes. We want to run this server on port `8081`. So, add the following line in `application.properties` file:
```
server.port=8081
```
Run the Spring Boot app using IDE or `./mvnw spring-boot:run` command. Then, visit `http://localhost:8081` in a browser. You should see the Angular starting app.

#### Explanation
In `angular.json` file we have specified `target/classes/static` as the output path of `ng build`. We have also defined to run `ng build` command whenever the spring boot app starts using **Frontend Maven Plugin**. Now, whenever the server starts, it builds the angular app and puts all the files in `target/classes/static` directory, which is the default directory to be served by the spring application. Now, whenever the user tries to access the spring boot app, `index.html` file from `target/classes/static` is served. Let's modify the `app.component.html` file of the angular app and replace its content with the following code:
```
<h3>{{title}}</h3>
<div>
  Welcome to {{title}}
</div>
```
Since `./ng build --watch` command is running. Angular CLI detects the changes in html file and rebuilds the angular app. Now, refresh the browser page and we see the updated page. That's how it works. Now, we are ready to add security 🔐 to the app.
### Secure the app using OAuth2
Now, let's make our app an OAuth2 client using `spring-boot-starter-oauth2-client` dependency. 
#### Adding the dependency
Add the `spring-boot-starter-oauth2-client` dependency to the spring boot app by inserting the following lines in the `pom.xml` file:
```
    <dependencies>
		...other dependencies

		<!-- To create OAuth2 Client -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-oauth2-client</artifactId>
		</dependency>

		... other dependencies
	</dependencies>
```
Now, our app is an OAuth2 client. We just need to configure it.
#### Creating app in Identity Provider
In [the first part](https://hpareek.hashnode.dev/authentication-using-oauth2-openid-connect-in-angular-single-page-application) of this series, we created an OAuth2 client in Authorization Server / Identity Provider. We chose Single Page Application and that is the reason Okta did not provide client secret for the app. But, now we are serving the app from a spring boot backend. And we can securely store credentials and access token in the backend. So, we need to create another app because we need client secrets this time. If you don't know how to create an app in Identity Provider, then read [the first part](https://hpareek.hashnode.dev/authentication-using-oauth2-openid-connect-in-angular-single-page-application)  here. Create a new app in Identity Provider, but this time chose **Web Application** as *Application Type* not **Single Page Application** since authentication and tokens will be managed on the server, not in the browser. Use `http://localhost:8081/login/oauth2/code/{IdentityProviderId}` as **Sign-in Redirect URI** and `http://localhost:8081` as **Sign-out Redirect URI** while creating the app. Here `IdentityProviderId` is the unique id of the identity provider with respect to our Spring Boot App. For example, you can use `okta` for **Okta**, `keycloak` for **Keycloak**, etc. At this point, you should have `client-id`, `client-secret`, and `issuer-uri` of the app. In case of Okta, the `issuer-uri` is `https://{OKTA_DOMAIN}/oauth2/default`.

#### Configuring Spring Boot App
Add the following configurations to the `application.properties` file of the app:
```
spring.security.oauth2.client.registration.{IdentityProviderId}.client-id={ClientId}
spring.security.oauth2.client.registration.{IdentityProviderId}.client-secret={ClientSecret}
spring.security.oauth2.client.registration.{IdentityProviderId}.scope=openid,profile,email
spring.security.oauth2.client.registration.{IdentityProviderId}.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.{IdentityProviderId}.redirect-uri={RedirectURI}
spring.security.oauth2.client.provider.{IdentityProviderId}.issuer-uri={IssuerURI}
```
Restart the app and visit `http://localhost:8081` in a private window of the browser. You are asked to Sign in to the app. Enter the username and password of any user which you created in Identity Provider (Please do so, if you haven't done already). After successful login, we can see our angular app. 

### Summary
In this article, we

✅ created a spring boot server, which serves an angular app.

✅ added OAuth2 authentication to the spring boot server to secure the angular app.

Source code can be found [here](https://github.com/himanshu-pareek/OAuth2SPA/tree/05_Serve_Ang_App_from_backend_OAuth2_flow) (`oauth2clientserver` directory). In the next article, I will explain how to use this Spring Boot Server as a proxy while making API requests to the Resource Server. Stay tuned for the next part. Thanks for reading. Keep learning...
