You are on page 1of 24

Application Monitoring with Spring Boot Actuator Read Now!

 Story  

Encadernação: cabeceados
eduK

Follow @devglan

Angular 7 CRUD Example (Full Monografias


e Tccs
Stack App) Cadeira
fabricadetccs.com

   By Dhiraj,   Last updated on: 18 April, 2018


146K
Elevador
Em até 48 horas.
Surimex
Professores mestres e
In this article, we will be creating a sample Angular 7 application step by step doutores especialistas
from scratch and perform CRUD operations on a user entity. The back-end API em diferentes
Para áreasedo
Escadas Retas
will be exposed using Spring Boot REST and MySQL will be used for persistent conhecimento.
Curvas com Qualidade
storage. We will be using Angular CLI to generate our sample project and then e Segurança para
we will add our all user components to it. We will have a login page with token- Idosos
based authentication. We will be using routing configuration to switch in
between the routes and ReactiveFormsModule for creating forms. We will also
be implementing HttpInterceptor at client side to intercept all the API request ABRIR
to add auth token in the header. Hence, in short, we will be creating a full stack Surimex Stairlift
app using angular 7 and spring boot.

Recommended

Angular Multiple File Upload

Channel Partners Want Your Content- OPEN Material Sidenav Example


ContentCast Delivers!
Rxjs Tutorial

Angular Data Table Example

You can follow this article for Angular 8 integration with Spring Boot.
Spring Boot Jwt Auth

Angular 8 just got released this May and here is the article for Angular 8 CRUD Spring Boot Angular Spring Data
example. Example

Angular 7 Release Highlights Angular Material Dialog

Angular Material App


Angular 7 got released this year in October with multiple new features such as
CLI Prompts, Virtual Scroll, Drag and Drop, Angular Budgets and many more. Typescript Tutorial
From this release, Angular supports Node 10 and simultaneously maintains
Node 8 support with TypeScript 3.1 and RxJS 6.3. A new extension from Angular Hide Sidenav Login
@angular/schematics called prompts has been introduced with the CLI that Page
will now prompt developers when running common commands such as ng
new my-app. Following is an example from the Angular Schematic for ng new:

"routing": {
"type": "boolean",
"description": "Generates a routing module.",
"default": false,
"x-prompt": "Would you like to add Angular routing?"
},
Application Monitoring with Spring Boot Actuator Read Now!
 Story  

Monografias
e Tccs
fabricadetccs.com

Em até 48 horas.
Project Structure Professores mestres e
doutores especialistas
Now, we can import the project in any IDE and check the the angular.json file to em diferentes áreas do
check the version of angular dependencies. Following are the different conhecimento.
components that we will be creating. You can download the source from
GitHub here.

ng g component login
ng g component add-user ABRIR
ng g component edit-user
ng g component list-user

Here, is the final project structure that we will creating by the end of this tutorial.

Angular 7 Login Component


For login component, we will have a reactive form that accepts username and
password. On submit, /login API is called which validates user credentials from
DB and returns user token. We will be caching this token in local storage. The
same token will be used in the subsequent request. Post login, user list page will
be rendered. We have all validations in place to check the required fields are
not empty. In a similar fashion, you can add multiple other validations such as
character min-length or email validations.

Following is the implementation.

login.component.html
<div class="row"> Application Monitoring with Spring Boot Actuator Read Now!
 Story  
<div class="col-md-6 login-container">
<h2 style="margin: auto">Login </h2>
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" formControlName="username" id="usernam
e" autocomplete="off">
<div class="error" *ngIf="loginForm.controls['username'].hasError('required')
&& loginForm.controls['username'].touched">Username is required</div>
</div>
Monografias
<div class="form-group">
<label for="pwd">Password:</label> e Tccs
<input type="password" class="form-control" formControlName="password" id="pw
fabricadetccs.com
d" autocomplete="off">
<div class="error" *ngIf="loginForm.controls['password'].hasError('required')
&& loginForm.controls['password'].touched">Password is required</div> Em até 48 horas.
</div>
<button class="btn btn-success" [disabled]="loginForm.invalid">Login</button> Professores mestres e
<div *ngIf="invalidLogin" class="error"> doutores especialistas
<div>Invalid credentials.</div>
</div>
em diferentes áreas do
</form> conhecimento.
</div>
</div>

ABRIR

The ApiService has all the HTTP request implementation that makes HTTP
request to our backend APIs.

login.component.ts
Application Monitoring with Spring Boot Actuator Read Now!
 Story  

Monografias
e Tccs
fabricadetccs.com

Angular 7 Environment Setup


Em até 48 horas.
Both the CLI and generated project have dependencies that require Node 10 Professores mestres e
and hence let us first install it on our local machine. You can download the doutores especialistas
latest version of Node js from here - Node Js Official. I have node 10.13.0 installed em diferentes áreas do
on my local which includes npm 6.4.1. To update NPM, you can run the following conhecimento.
command in the terminal.

npm i npm@latest -g

ABRIR
If u have an older @angular/cli version, then you can run following command
to install the latest versions:

npm uninstall -g @angular/cli


npm cache clean
npm install -g @angular/cli

You can run below commands to check the versions on your local machine.

Other Interesting Posts


Angular PayuMoney Integration
Angular Server Side Rendering Example
Angular Material Sidenav Example
Spring Boot Angular Captcha
Deploy Angular App on Nginx
Angular 6 CRUD Example
Angular JWT Authentication
Angular Material App Example
Typescript Basic Tutorial
Spring Boot Angular Deployment
Spring Boot Angular Example

Generating Angular 7 Project from CLI


Traverse to your folder of choice and execute following commands to
generate and run Angular 7 app.

ng new my-dream-app
cd my-dream-app
ng serve

Now, you can open your browser and hit localhost:4200 to see the welcome
page. Below is the screenshot.
Application Monitoring with Spring Boot Actuator Read Now!
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';  Story  
import {User} from "../model/user.model";
import {Observable} from "rxjs/index";
import {ApiResponse} from "../model/api.response";

@Injectable()
export class ApiService {

constructor(private http: HttpClient) { }


baseUrl: string = 'http://localhost:8080/users/';
Monografias
login(loginPayload) : Observable<ApiResponse> {
return this.http.post<ApiResponse>('http://localhost:8080/'+ 'token/generate-toke e Tccs
n', loginPayload).pipe(
fabricadetccs.com
catchError(val => of(val)));
};
} Em até 48 horas.
getUsers() : Observable<ApiResponse> { Professores mestres e
return this.http.get<ApiResponse>(this.baseUrl); doutores especialistas
}
em diferentes áreas do
getUserById(id: number): Observable<ApiResponse> { conhecimento.
return this.http.get<ApiResponse>(this.baseUrl + id);
}

createUser(user: User): Observable<ApiResponse> {


return this.http.post<ApiResponse>(this.baseUrl, user);
}
ABRIR
updateUser(user: User): Observable<ApiResponse> {
return this.http.put<ApiResponse>(this.baseUrl + user.id, user);
}

deleteUser(id: number): Observable<ApiResponse> {


return this.http.delete<ApiResponse>(this.baseUrl + id);
}
}

Angular 7 User Components

List User

After a successfull login, list-user route will be loaded and getUsers() will be
invoked that will load the list of users and the user list will be shown in a tabular
form. Each row will have button to either update or delete a user entry. Add
button will open a new form to add a new user. On click of edit button, edit
component will be loaded with user details auto populated where we can edit
the user details and save the changes and click on delete button will instantly
delete the user from DB and update the table.Following is the implementation.

list-user.component.html
<div class="col-md-6 user-container"> Application Monitoring with Spring Boot Actuator Read Now!
<h2 style="margin: auto"> User Details</h2>  Story  
<button class="btn btn-danger" style="width:100px" (click)="addUser()"> Add User</bu
tton>
<table class="table table-striped">
<thead>
<tr>
<th class="hidden">Id</th>
<th>FirstName</th>
<th>LastName</th>
<th>UserName</th>
<th>Age</th>
Monografias
<th>Salary</th>
</tr> e Tccs
</thead>
fabricadetccs.com
<tbody>
<tr *ngFor="let user of users">
<td class="hidden"></td> Em até 48 horas.
<td></td>
<td></td> Professores mestres e
<td></td> doutores especialistas
<td></td>
<td></td>
em diferentes áreas do
<td><button class="btn btn-success" (click)="deleteUser(user)"> Delete</button> conhecimento.
<button class="btn btn-success" (click)="editUser(user)" style="margin-left: 2
0px;"> Edit</button></td>
</tr>
</tbody>
</table>
</div>
ABRIR

Post login, all the APIs are secured and hence requires token to perform
authentication amd authorization at the server. Instead of duplicating code to
add the token in every request, we have implemented HTTPInterceptor that
intercepts all the HTTP request and adds required token in the header. The
implementation is in the subsequent heading.

list-user.component.ts
Application Monitoring with Spring Boot Actuator Read Now!
import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";  Story  
import {Router} from "@angular/router";
import {ApiService} from "../core/api.service";

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
Monografias
loginForm: FormGroup;
invalidLogin: boolean = false; e Tccs
constructor(private formBuilder: FormBuilder, private router: Router, private apiSer
fabricadetccs.com
vice: ApiService) { }

onSubmit() { Em até 48 horas.


if (this.loginForm.invalid) {
return; Professores mestres e
} doutores especialistas
const loginPayload = {
username: this.loginForm.controls.username.value,
em diferentes áreas do
password: this.loginForm.controls.password.value conhecimento.
}
this.apiService.login(loginPayload).subscribe(data => {
if(data.status === 200) {
window.localStorage.setItem('token', data.result.token);
this.router.navigate(['list-user']);
}else {
ABRIR
this.invalidLogin = true;
alert(data.message);
}
});
}

ngOnInit() {
window.localStorage.removeItem('token');
this.loginForm = this.formBuilder.group({
username: ['', Validators.compose([Validators.required])],
password: ['', Validators.required]
});
}

Angular 7 Service Implementation


We have 6 API implementation for CRUD operations including login API for user
authentication. For now, let us assume our user endpoint is
localhost:8080/users. Below is the implementation.All the API response has
uniform response data format as below.

{
"status": 200,
"message": "",
"result": {}

api.service.ts
Application
import { Component, OnInit , Inject} from Monitoring with Spring Boot Actuator Read Now!
'@angular/core';
import {Router} from "@angular/router";  Story  
import {User} from "../model/user.model";
import {ApiService} from "../core/api.service";

@Component({
selector: 'app-list-user',
templateUrl: './list-user.component.html',
styleUrls: ['./list-user.component.css']
})
export class ListUserComponent implements OnInit {
Monografias
users: User[];
e Tccs
constructor(private router: Router, private apiService: ApiService) { }
fabricadetccs.com

ngOnInit() {
if(!window.localStorage.getItem('token')) { Em até 48 horas.
this.router.navigate(['login']);
return; Professores mestres e
} doutores especialistas
this.apiService.getUsers()
.subscribe( data => {
em diferentes áreas do
this.users = data.result; conhecimento.
});
}

deleteUser(user: User): void {


this.apiService.deleteUser(user.id)
.subscribe( data => {
ABRIR
this.users = this.users.filter(u => u !== user);
})
};

editUser(user: User): void {


window.localStorage.removeItem("editUserId");
window.localStorage.setItem("editUserId", user.id.toString());
this.router.navigate(['edit-user']);
};

addUser(): void {
this.router.navigate(['add-user']);
};
}

Edit User

Whenever, user clicks on the edit button, the selected id is stored in the cache
first and when edit route is loaded, the cached id is used to fetch user details
from the server and auto populate the edit user form.

edit-user.component.html
<div class="col-md-6 user-container"> Application Monitoring with Spring Boot Actuator Read Now!
<h2 class="text-center">Edit User</h2>  Story  
<form [formGroup]="editForm" (ngSubmit)="onSubmit()">
<div class="hidden">
<input type="text" formControlName="id" placeholder="id" name="id" class="form-c
ontrol" id="id">
</div>
<div class="form-group">
<label for="username">User Name:</label>
<input type="text" formControlName="username" placeholder="username" name="usern
ame" class="form-control" id="username" readonly="true">
</div>
Monografias
<div class="form-group"> e Tccs
<label for="firstName">First Name:</label>
fabricadetccs.com
<input formControlName="firstName" placeholder="First Name" name="firstName" cla
ss="form-control" id="firstName">
</div> Em até 48 horas.
<div class="form-group"> Professores mestres e
<label for="lastName">Last Name:</label> doutores especialistas
<input formControlName="lastName" placeholder="Last name" name="lastName" class
="form-control" id="lastName">
em diferentes áreas do
</div> conhecimento.

<div class="form-group">
<label for="age">Age:</label>
<input type="number" formControlName="age" placeholder="age" name="age" class="f
orm-control" id="age">
</div>
ABRIR
<div class="form-group">
<label for="salary">Salary:</label>
<input type="number" formControlName="salary" placeholder="salary" name="salary"
class="form-control" id="salary">
</div>

<button class="btn btn-success">Update</button>


</form>
</div>

edit-user.component.ts
Application
import { Component, OnInit , Inject} from Monitoring with Spring Boot Actuator Read Now!
'@angular/core';
import {Router} from "@angular/router";  Story  
import {User} from "../model/user.model";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {first} from "rxjs/operators";
import {ApiService} from "../core/api.service";

@Component({
selector: 'app-edit-user',
templateUrl: './edit-user.component.html',

})
styleUrls: ['./edit-user.component.css']
Monografias
export class EditUserComponent implements OnInit {
e Tccs
user: User;
fabricadetccs.com
editForm: FormGroup;
constructor(private formBuilder: FormBuilder,private router: Router, private apiServ
ice: ApiService) { } Em até 48 horas.
ngOnInit() { Professores mestres e
let userId = window.localStorage.getItem("editUserId"); doutores especialistas
if(!userId) {
alert("Invalid action.")
em diferentes áreas do
this.router.navigate(['list-user']); conhecimento.
return;
}
this.editForm = this.formBuilder.group({
id: [''],
username: ['', Validators.required],
firstName: ['', Validators.required],
ABRIR
lastName: ['', Validators.required],
age: ['', Validators.required],
salary: ['', Validators.required]
});
this.apiService.getUserById(+userId)
.subscribe( data => {
this.editForm.setValue(data.result);
});
}

onSubmit() {
this.apiService.updateUser(this.editForm.value)
.pipe(first())
.subscribe(
data => {
if(data.status === 200) {
alert('User updated successfully.');
this.router.navigate(['list-user']);
}else {
alert(data.message);
}
},
error => {
alert(error);
});
}

Add user

Similarly, we have add user implementation below.

add-user.component.html
<div class="col-md-6 user-container"> Application Monitoring with Spring Boot Actuator Read Now!
<h2 class="text-center">Add User</h2>  Story  
<form [formGroup]="addForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">User Name:</label>
<input type="text" formControlName="username" placeholder="username" name="usern
ame" class="form-control" id="username">
</div>

<div class="form-group">
<label for="password">Password:</label>
<input type="password" formControlName="password" placeholder="password" name="p
Monografias
assword" class="form-control" id="password">
</div> e Tccs
fabricadetccs.com
<div class="form-group">
<label for="firstName">First Name:</label>
<input formControlName="firstName" placeholder="First Name" name="firstName" cla Em até 48 horas.
ss="form-control" id="firstName">
</div> Professores mestres e
doutores especialistas
<div class="form-group">
<label for="lastName">Last Name:</label>
em diferentes áreas do
<input formControlName="lastName" placeholder="Last name" name="lastName" class conhecimento.
="form-control" id="lastName">
</div>

<div class="form-group">
<label for="age">Age:</label>
<input type="number" formControlName="age" placeholder="age" name="age" class="f
ABRIR
orm-control" id="age">
</div>

<div class="form-group">
<label for="salary">Salary:</label>
<input type="number" formControlName="salary" placeholder="salary" name="salary"
class="form-control" id="salary">
</div>

<button class="btn btn-success">Update</button>


</form>
</div>

add-user.component.ts
import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {Router} from "@angular/router";
import {ApiService} from "../core/api.service";

@Component({
selector: 'app-add-user',
templateUrl: './add-user.component.html',
styleUrls: ['./add-user.component.css']
})
export class AddUserComponent implements OnInit {

constructor(private formBuilder: FormBuilder,private router: Router, private apiServ


ice: ApiService) { }

addForm: FormGroup;

ngOnInit() {
this.addForm = this.formBuilder.group({
id: [],
username: ['', Validators.required],
password: ['', Validators.required],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
age: ['', Validators.required],
salary: ['', Validators.required]
});

onSubmit() {
this.apiService.createUser(this.addForm.value)
.subscribe( data => {
this.router.navigate(['list-user']);
});
}

Angular 7 HTTP Interceptor


Application Monitoring with Spring Boot Actuator Read Now!
The interceptor implements HttpInterceptor which intercepts all the HTTP  Story  
request and token in the header for API authentication. Following is the
implementation.

During login, there won't be any token present in the local cache hence, there is
a condition check for presence of token.

interceptor.ts
Monografias
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/ht
tp";
e Tccs
import {Observable} from "rxjs/internal/Observable"; fabricadetccs.com
import {Injectable} from "@angular/core";

@Injectable()
Em até 48 horas.
export class TokenInterceptor implements HttpInterceptor {
Professores mestres e
intercept(request: HttpRequest, next: HttpHandler): Observable> {
doutores especialistas
let token = window.localStorage.getItem('token'); em diferentes áreas do
debugger conhecimento.
if (token) {
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + token
}
});
} ABRIR
return next.handle(request);
}
}

App Module Implementation


app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';


import { LoginComponent } from './login/login.component';
import { AddUserComponent } from './add-user/add-user.component';
import { EditUserComponent } from './edit-user/edit-user.component';
import { ListUserComponent } from './list-user/list-user.component';
import {ApiService} from "./core/api.service";
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
import {ReactiveFormsModule} from "@angular/forms";
import {routing} from "./app.routing";
import {TokenInterceptor} from "./core/interceptor";

@NgModule({
declarations: [
AppComponent,
LoginComponent,
AddUserComponent,
EditUserComponent,
ListUserComponent
],
imports: [
BrowserModule,
routing,
ReactiveFormsModule,
HttpClientModule
],
providers: [ApiService, {provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi : true}],
bootstrap: [AppComponent]
})
export class AppModule { }
Application Monitoring with Spring Boot Actuator Read Now!

Spring Boot Server Implementation


 Story  

We have created multiple applications in my previous articles on spring boot


security. All the examples are available here - Spring Boot Security Apps. Here,
again we will be creating another spring boot app and integrate JWT with it for
authentication and authorization. You can actually follow Spring Boot Security
JWT article for step by step explanation as we may skip common explanation Monografias
and implementations here and you can download the source from here.
e Tccs
First, let us head over to start.spring.io to generate a sample spring boot project fabricadetccs.com

and then import it into your workspace and then make changes in it to
integrate JWT. Following will be our spring boot project structure. Em até 48 horas.
Professores mestres e
doutores especialistas
em diferentes áreas do
conhecimento.

ABRIR

JWT Token Validation


Following class extends OncePerRequestFilter that ensures a single execution
per request dispatch. This class checks for the authorization header and
authenticates the JWT token and sets the authentication in the context.Doing
so will protect our APIs from those requests which do not have any
authorization token.The configuration about which resource to be protected
and which not can be configured in WebSecurityConfig.java
package com.devglan.config; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToke
n;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
Monografias
import org.springframework.web.filter.OncePerRequestFilter;
e Tccs
import javax.servlet.FilterChain;
fabricadetccs.com
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; Em até 48 horas.
import java.io.IOException;
import java.util.Arrays; Professores mestres e
doutores especialistas
import static com.devglan.model.Constants.HEADER_STRING;
import static com.devglan.model.Constants.TOKEN_PREFIX;
em diferentes áreas do
conhecimento.
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
private UserDetailsService userDetailsService;

@Autowired
ABRIR
private JwtTokenUtil jwtTokenUtil;

@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, F
ilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
String username = null;
String authToken = null;
if (header != null && header.startsWith(TOKEN_PREFIX)) {
authToken = header.replace(TOKEN_PREFIX,"");
try {
username = jwtTokenUtil.getUsernameFromToken(authToken);
} catch (IllegalArgumentException e) {
logger.error("an error occured during getting username from token",
e);
} catch (ExpiredJwtException e) {
logger.warn("the token is expired and not valid anymore", e);
} catch(SignatureException e){
logger.error("Authentication Failed. Username or Password not vali
d.");
}
} else {
logger.warn("couldn't find bearer string, will ignore the header");
}
if (username != null && SecurityContextHolder.getContext().getAuthentication()
== null) {

UserDetails userDetails = userDetailsService.loadUserByUsername(username);

if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePassw
ordAuthenticationToken(userDetails, null, Arrays.asList(new SimpleGrantedAuthority("RO
LE_ADMIN")));
authentication.setDetails(new WebAuthenticationDetailsSource().buildDe
tails(req));
logger.info("authenticated user " + username + ", setting security con
text");
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}

chain.doFilter(req, res);
}
}

Spring Boot Web Security Config


Below is the implementation of our security config that does not requires any
authorization for endpoints token/* and /signup. Rest all the endpoints related to
users are secured.

WebSecurityConfig.java
package com.devglan.config; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.Authenti
cationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGloba
lMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Monografias
import org.springframework.security.config.annotation.web.configuration.EnableWebSecur
ity; e Tccs
import org.springframework.security.config.annotation.web.configuration.WebSecurityCon
fabricadetccs.com
figurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService; Em até 48 horas.
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationF Professores mestres e
ilter; doutores especialistas
import javax.annotation.Resource;
em diferentes áreas do
conhecimento.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Resource(name = "userService")
ABRIR
private UserDetailsService userDetailsService;

@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}

@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/token/*", "/signup").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and
()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATE
LESS);
http
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuth
enticationFilter.class);
}

@Bean
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}

Spring Boot Controller


We have 2 controller defined here. One for generating token i.e. sign up which is
not secured and the other is usercontroller which requires authentication.

API Details
API Name - Token Generation Application Monitoring with Spring Boot Actuator Read Now!
URL - localhost:8080/token/generate-token  Story  
Method - POST
Header - Content-Type: application/json
Body -
{
"username":"alex123",
"password":"alex123"
}

Response :
Monografias
{
"status": 200, e Tccs
"message": "success",
fabricadetccs.com
"result": {
"token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGV4MTIzIiwic2NvcGVzIjpbeyJhdXRob3J
pdHkiOiJST0xFX0FETUlOIn1dLCJpc3MiOiJodHRwOi8vZGV2Z2xhbi5jb20iLCJpYXQiOjE1NDEwNjIzOTMsI Em até 48 horas.
mV4cCI6MTU0MTA4MDM5M30.DMoB5kv72X7Jf-U5APdjK3UUcGomA9NuJj6XGxmLyqE",
"username": "alex123" Professores mestres e
} doutores especialistas
}
em diferentes áreas do
API Name - List User conhecimento.
URL - http://localhost:8080/users
Method - Get
Header - Content-Type: application/json
Authorization : Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGV4MTIzIiwic2NvcGVzIjpbey
JhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dLCJpc3MiOiJodHRwOi8vZGV2Z2xhbi5jb20iLCJpYXQiOjE1NDEw
NjIzOTMsImV4cCI6MTU0MTA4MDM5M30.DMoB5kv72X7Jf-U5APdjK3UUcGomA9NuJj6XGxmLyqE
ABRIR
Response -
{
"status": 200,
"message": "User list fetched successfully.",
"result": [
{
"id": 1,
"firstName": "Alex",
"lastName": "Knr",
"username": "alex123",
"salary": 3456,
"age": 33
},
{
"id": 2,
"firstName": "Tom",
"lastName": "Asr",
"username": "tom234",
"salary": 7823,
"age": 23
},
{
"id": 3,
"firstName": "Adam",
"lastName": "Psr",
"username": "adam",
"salary": 4234,
"age": 45
}
]
}

API Name - Create User


URL - http://localhost:8080/users
Method - POST
Header - Content-Type: application/json
Authorization : Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGV4MTIzIiwic2NvcGVzIjpbey
JhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dLCJpc3MiOiJodHRwOi8vZGV2Z2xhbi5jb20iLCJpYXQiOjE1NDEw
NjIzOTMsImV4cCI6MTU0MTA4MDM5M30.DMoB5kv72X7Jf-U5APdjK3UUcGomA9NuJj6XGxmLyqE
Body -
{
"username":"test",
"password":"test",
"firstName":"test",
"lastName":"test",
"age":23,
"salary":12345
}

Response -

{
"status": 200,
"message": "User saved successfully.",
"result": {
"id": 4,
"firstName": "test",
"lastName": "test"",
"username": "test",
package com.devglan.controller; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import com.devglan.config.JwtTokenUtil;
import com.devglan.model.*;
import com.devglan.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToke
n;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
Monografias
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*; e Tccs
fabricadetccs.com
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/token") Em até 48 horas.
public class AuthenticationController {
Professores mestres e
@Autowired doutores especialistas
private AuthenticationManager authenticationManager;
em diferentes áreas do
@Autowired conhecimento.
private JwtTokenUtil jwtTokenUtil;

@Autowired
private UserService userService;

@RequestMapping(value = "/generate-token", method = RequestMethod.POST)


ABRIR
public ApiResponse register(@RequestBody LoginUser loginUser) throws Authenticatio
nException {

authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(log
inUser.getUsername(), loginUser.getPassword()));
final User user = userService.findOne(loginUser.getUsername());
final String token = jwtTokenUtil.generateToken(user);
return new ApiResponse<>(200, "success",new AuthToken(token, user.getUsername
()));
}

UserController.java
"salary": 12345, Application Monitoring with Spring Boot Actuator Read Now!
"age": 23  Story  
}
}

API Name - Update User


URL - http://localhost:8080/users/4
Method - PUT
Header - Content-Type: application/json

Monografias
Authorization : Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGV4MTIzIiwic2NvcGVzIjpbey
JhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dLCJpc3MiOiJodHRwOi8vZGV2Z2xhbi5jb20iLCJpYXQiOjE1NDEw
NjIzOTMsImV4cCI6MTU0MTA4MDM5M30.DMoB5kv72X7Jf-U5APdjK3UUcGomA9NuJj6XGxmLyqE
Body -
{
e Tccs
"username":"test1", fabricadetccs.com
"password":"test1",
"firstName":"test1",
Em até 48 horas.
"lastName":"test1",
"age":24, Professores mestres e
"salary":12345
}
doutores especialistas
em diferentes áreas do
Response - conhecimento.
{
"status": 200,
"message": "User updated successfully.",
"result": {
"id": 0,
"firstName": "test1", ABRIR
"lastName": "test1",
"username": "test1",
"password": "test1",
"age": 24,
"salary": 12345
}
}

API Name - Delete User


URL - http://localhost:8080/users/4
Method - DELETE
Header - Content-Type: application/json
Authorization : Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGV4MTIzIiwic2NvcGVzIjpbey
JhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dLCJpc3MiOiJodHRwOi8vZGV2Z2xhbi5jb20iLCJpYXQiOjE1NDEw
NjIzOTMsImV4cCI6MTU0MTA4MDM5M30.DMoB5kv72X7Jf-U5APdjK3UUcGomA9NuJj6XGxmLyqE

Response -
{
"status": 200,
"message": "User deleted successfully.",
"result": null
}

Monografias e Tccs - Em até 48 horas.

Ad Professores mestres e doutores especialistas em diferentes áreas do conheciment


Ad
fabricadetccs.com

Saber mais

AuthenticationController.java
package com.devglan.controller; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import com.devglan.model.ApiResponse;
import com.devglan.model.User;
import com.devglan.model.UserDto;
import com.devglan.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Monografias
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController e Tccs
@RequestMapping("/users")
fabricadetccs.com
public class UserController {

@Autowired Em até 48 horas.


private UserService userService;
Professores mestres e
@PostMapping doutores especialistas
public ApiResponse saveUser(@RequestBody UserDto user){
return new ApiResponse<>(HttpStatus.OK.value(), "User saved successfully.",use
em diferentes áreas do
rService.save(user)); conhecimento.
}

@GetMapping
public ApiResponse> listUser(){
return new ApiResponse<>(HttpStatus.OK.value(), "User list fetched successfull
y.",userService.findAll());
ABRIR
}

@GetMapping("/{id}")
public ApiResponse getOne(@PathVariable int id){
return new ApiResponse<>(HttpStatus.OK.value(), "User fetched successfully.",u
serService.findById(id));
}

@PutMapping("/{id}")
public ApiResponse update(@RequestBody UserDto userDto) {
return new ApiResponse<>(HttpStatus.OK.value(), "User updated successfully.",u
serService.update(userDto));
}

@DeleteMapping("/{id}")
public ApiResponse delete(@PathVariable int id) {
userService.delete(id);
return new ApiResponse<>(HttpStatus.OK.value(), "User fetched successfully.",
null);
}

Spring Boot Service implementation


The service implementation is very simple which communicates with spring
data JPA to fetch rows from DB. One thing to remeber here is that we are
saving Bcrypt encoded password in the DB.

UserService.java
package com.devglan.service.impl; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import com.devglan.dao.UserDao;
import com.devglan.model.User;
import com.devglan.model.UserDto;
import com.devglan.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
Monografias
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; e Tccs
fabricadetccs.com
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; Em até 48 horas.
import java.util.Optional;
Professores mestres e
doutores especialistas
@Service(value = "userService")
public class UserServiceImpl implements UserDetailsService, UserService {
em diferentes áreas do
conhecimento.
@Autowired
private UserDao userDao;

@Autowired
private BCryptPasswordEncoder bcryptEncoder;

ABRIR
public UserDetails loadUserByUsername(String username) throws UsernameNotFound
Exception {
User user = userDao.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("Invalid username or passw
ord.");
}
return new org.springframework.security.core.userdetails.User(user.get
Username(), user.getPassword(), getAuthority());
}

private List getAuthority() {


return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
}

public List findAll() {


List list = new ArrayList<>();
userDao.findAll().iterator().forEachRemaining(list::add);
return list;
}

@Override
public void delete(int id) {
userDao.deleteById(id);
}

@Override
public User findOne(String username) {
return userDao.findByUsername(username);
}

@Override
public User findById(int id) {
Optional optionalUser = userDao.findById(id);
return optionalUser.isPresent() ? optionalUser.get() : null;
}

@Override
public UserDto update(UserDto userDto) {
User user = findById(userDto.getId());
if(user != null) {
BeanUtils.copyProperties(userDto, user, "password");
userDao.save(user);
}
return userDto;
}

@Override
public User save(UserDto user) {
User newUser = new User();
newUser.setUsername(user.getUsername());
newUser.setFirstName(user.getFirstName());
newUser.setLastName(user.getLastName());
newUser.setPassword(bcryptEncoder.encode(user.getPassword()));
newUser.setAge(user.getAge());
newUser.setSalary(user.getSalary());
return userDao.save(newUser);
}
} Application Monitoring with Spring Boot Actuator Read Now!
 Story  

Model Class Implementation


User.java

Monografias
e Tccs
fabricadetccs.com

Em até 48 horas.
Professores mestres e
doutores especialistas
em diferentes áreas do
conhecimento.

ABRIR
package com.devglan.model; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;

@Entity
@Table(name = "user")
public class User {

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
Monografias
private int id;
@Column e Tccs
private String firstName;
fabricadetccs.com
@Column
private String lastName;
@Column Em até 48 horas.
private String username;
@Column Professores mestres e
@JsonIgnore doutores especialistas
private String password;
@Column
em diferentes áreas do
private long salary; conhecimento.
@Column
private int age;

public int getId() {


return id;
}
ABRIR
public void setId(int id) {
this.id = id;
}

public String getFirstName() {


return firstName;
}

public void setFirstName(String firstName) {


this.firstName = firstName;
}

public String getLastName() {


return lastName;
}

public void setLastName(String lastName) {


this.lastName = lastName;
}

public String getUsername() {


return username;
}

public void setUsername(String username) {


this.username = username;
}

public String getPassword() {


return password;
}

public void setPassword(String password) {


this.password = password;
}

public long getSalary() {


return salary;
}

public void setSalary(long salary) {


this.salary = salary;
}

public int getAge() {


return age;
}

public void setAge(int age) {


this.age = age;
}
}

UserDto.java
package com.devglan.model; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
public class UserDto {

private int id;


private String firstName;
private String lastName;
private String username;
private String password;
private int age;
private int salary;
Monografias
}
e Tccs
fabricadetccs.com

Following is the DB config we are using.


Em até 48 horas.

application.properties Professores mestres e


spring.datasource.url=jdbc:mysql://localhost:3306/test
doutores especialistas
spring.datasource.username=root em diferentes áreas do
spring.datasource.password=root conhecimento.
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.user.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.Physical
NamingStrategyStandardImpl

ABRIR
Below is the DB scripts.

CREATE TABLE user(id INT NOT NULL AUTO_INCREMENT,age INT,firstName VARCHAR(255),lastNa


me VARCHAR(255),password VARCHAR(255),salary BIGINT,username VARCHAR(255),PRIMARY KEY
(id))ENGINE=MyISAM;

INSERT INTO User (id, firstname, lastname, username, password, salary, age) VALUES (1,
'Alex','Knr', 'alex123','$2a$04$4vwa/ugGbBVDvbWaKUVZBuJbjyQyj6tqntjSmG8q.hi97.xSdhj/
2', 3456, 33);
INSERT INTO User (id, firstname, lastname, username, password, salary, age) VALUES
(2, 'Tom', 'Asr', 'tom234', '$2a$04$QED4arFwM1AtQWkR3JkQx.hXxeAk/G45NiRd3Q4ElgZdzGYCYK
ZOW', 7823, 23);
INSERT INTO User (id, firstname, lastname, username, password, salary, age) VALUES
(3, 'Adam', 'Psr', 'adam', '$2a$04$WeT1SvJaGjmvQj34QG8VgO9qdXecKOYKEDZtCPeeIBSTxxEhazN
la', 4234, 45);

Adding CORS with Spring Boot Angular


Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional
HTTP headers to tell a browser to let a web application running at one origin
(domain) have permission to access selected resources from a server at a
different origin. Since, we have server running at localhost:8080 and angular
running at localhost:4200, we see error as No 'Access-Control-Allow-Origin'. To
avoid this error, we can add below filter in the spring project.
package com.devglan.config; Application Monitoring with Spring Boot Actuator Read Now!
 Story  
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
Monografias
public class CORSFilter implements Filter { e Tccs
fabricadetccs.com
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chai
n) throws IOException, ServletException {
System.out.println("Filtering o Em até 48 horas.
n...........................................................");
HttpServletResponse response = (HttpServletResponse) res; Professores mestres e
response.setHeader("Access-Control-Allow-Origin", "*"); doutores especialistas
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OP
em diferentes áreas do
TIONS, DELETE"); conhecimento.
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-
Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Req
uest-Headers");

chain.doFilter(req, res);
ABRIR
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

Conclusion
This is pretty much implementation of a full stack app using Angular 7 and
Spring Boot with JWT authentication. I know you need the source code now. You
can download it from this link for the same. It has both the server and client
project.If you want to add anything else then please let me know in the
comments below.

If You Appreciate This, You Can Consider:

Like us at: or follow us at


Share this article on social media or with your teammates.

About The Author

A technology savvy professional with an exceptional


capacity to analyze, solve problems and multi-task. Technical
expertise in highly scalable distributed systems, self-healing
systems, and service-oriented architecture. Technical Skills:
Java/J2EE, Spring, Hibernate, Reactive Programming,
Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana,
Elasticsearch, etc.

Further Reading on Angular JS


1. Angular Multiple File Upload

2. Material Sidenav Example

3. Rxjs Tutorial

4. Angular Data Table Example

5. Spring Boot Jwt Auth

6. Spring Boot Angular Spring Data Example

7. Angular Material Dialog

8. Angular Material App

You might also like