0% found this document useful (0 votes)
179 views50 pages

Spring Boot JWT Security-Mr - RAGHU Spring Boot Application: Raghu Sir (Naresh I Technologies, Ameerpet, Hyderabad)

This document outlines the code for a Spring Boot application that implements JWT authentication. It includes the configuration properties, SQL scripts to set up the database, request/response classes, entity models, repository interfaces, and a utility class for mapping roles. The application uses JWT tokens to authenticate users and roles stored in the database to authorize access.

Uploaded by

Varun Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
179 views50 pages

Spring Boot JWT Security-Mr - RAGHU Spring Boot Application: Raghu Sir (Naresh I Technologies, Ameerpet, Hyderabad)

This document outlines the code for a Spring Boot application that implements JWT authentication. It includes the configuration properties, SQL scripts to set up the database, request/response classes, entity models, repository interfaces, and a utility class for mapping roles. The application uses JWT tokens to authenticate users and roles stored in the database to authorize access.

Uploaded by

Varun Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

Spring Boot JWT Security-Mr.RAGHU

Spring Boot Application


a. application.properties
server.port=9900

server.servlet.context-path=/api

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/bootdb
spring.datasource.username=root
spring.datasource.password=root

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect

raghu.app.jwtSecret=NITRAGHU
raghu.app.jwtExpTimeInMs=88800000

b. Setup SQLs
create database bootdb;
use bootdb;
insert into roles_tab(name) values('ROLE_USER');
insert into roles_tab(name) values('ROLE_MODERATOR');
insert into roles_tab(name) values('ROLE_ADMIN');

c. Request and Response classes


package in.nareshit.raghu.request;

import javax.validation.constraints.NotBlank;

import lombok.Data;

1|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
@Data
public class LoginRequest {

@NotBlank
private String username;

@NotBlank
private String password;
}

package in.nareshit.raghu.request;

import java.util.Set;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import lombok.Data;

@Data
public class SignupRequest {

@NotBlank
@Size(min = 3, max = 20)
private String username;

@NotBlank
@Size(max=50)
@Email
private String email;

@NotBlank
@Size(min = 4, max = 40)
private String password;

private Set<String> role;

2|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}

package in.nareshit.raghu.response;

import java.util.Set;

import lombok.Data;
import lombok.NonNull;

@Data
public class JwtResponse {

@NonNull
private String token;

private String type = "Bearer";

@NonNull
private Long id;

@NonNull
private String username;

@NonNull
private String email;

@NonNull
private Set<String> roles;
}

package in.nareshit.raghu.response;

import lombok.AllArgsConstructor;
import lombok.Data;

3|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
@Data
@AllArgsConstructor
public class MessageResponse {

private String message;


}

d. Models
package in.nareshit.raghu.model;

public enum ERole {


ROLE_USER,
ROLE_MODERATOR,
ROLE_ADMIN
}

package in.nareshit.raghu.model;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name="roles_tab")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@Enumerated(EnumType.STRING)
private ERole name;

4|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}

package in.nareshit.raghu.model;

import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
@Table(
name="users_tab",
uniqueConstraints = {
@UniqueConstraint(columnNames = "username"),
@UniqueConstraint(columnNames = "email")
})
public class User {

@Id
5|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotBlank
@Size(max=20)
@NonNull
private String username;

@NotBlank
@Size(max=50)
@Email
@NonNull
private String email;

@NotBlank
@Size(max=120)
@NonNull
private String password;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name="users_roles_tab",
joinColumns = @JoinColumn(name="user_id"),
inverseJoinColumns = @JoinColumn(name="role_id")
)
private Set<Role> roles;

package in.nareshit.raghu.model;

import java.util.Collection;
import java.util.stream.Collectors;

import org.springframework.security.core.GrantedAuthority;
import
org.springframework.security.core.authority.SimpleGrantedAuthori
ty;

6|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import
org.springframework.security.core.userdetails.UserDetails;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {

private static final long serialVersionUID = 1L;

private Long id;


private String username;
private String email;

@JsonIgnore
private String password;

private Collection<? extends GrantedAuthority> authorities;

public static UserDetailsImpl build(User user) {


return new UserDetailsImpl(
user.getId(),
user.getUsername(),
user.getEmail(),
user.getPassword(),
user.getRoles()
.stream()
.map(role -> new
SimpleGrantedAuthority(role.getName().name()))
.collect(Collectors.toList())
);
}

public Collection<? extends GrantedAuthority>


getAuthorities() {

7|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
return authorities;
}

public String getPassword() {


return password;
}

public String getUsername() {


return username;
}

public boolean isAccountNonExpired() {


return true;
}

public boolean isAccountNonLocked() {


return true;
}

public boolean isCredentialsNonExpired() {


return true;
}

public boolean isEnabled() {


return true;
}

e. Repository Interfaces

package in.nareshit.raghu.repo;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import in.nareshit.raghu.model.ERole;

8|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import in.nareshit.raghu.model.Role;

public interface RoleRepository extends JpaRepository<Role,


Integer>{

Optional<Role> findByName(ERole name);


}

package in.nareshit.raghu.repo;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import in.nareshit.raghu.model.User;

public interface UserRepository extends JpaRepository<User,


Long>{

Optional<User> findByUsername(String username);


boolean existsByUsername(String username);
boolean existsByEmail(String email);
}

f. Utils
package in.nareshit.raghu.util;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import in.nareshit.raghu.model.ERole;
import in.nareshit.raghu.model.Role;
import in.nareshit.raghu.repo.RoleRepository;

@Component

9|Page
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
public class RolesUtils {

@Autowired
private RoleRepository repository;

public void mapRoles(Set<String> userRoles, Set<Role>


dbRoles) {

if(userRoles == null || userRoles.isEmpty()) {


Role userRole =
repository.findByName(ERole.ROLE_USER)
.orElseThrow(()->new
RuntimeException("Error: Role is not found"));
dbRoles.add(userRole);
} else {
userRoles.forEach(role->{
switch (role) {
case "admin":
Role adminRole =
repository.findByName(ERole.ROLE_ADMIN)
.orElseThrow(()->new
RuntimeException("Error: Role is not found"));
dbRoles.add(adminRole);
break;

case "mod":
Role modRole =
repository.findByName(ERole.ROLE_MODERATOR)
.orElseThrow(()->new
RuntimeException("Error: Role is not found"));
dbRoles.add(modRole);
break;

default:
Role userRole =
repository.findByName(ERole.ROLE_USER)
.orElseThrow(()->new
RuntimeException("Error: Role is not found"));
dbRoles.add(userRole);

10 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
break;
}
});
}

}
}

package in.nareshit.raghu.util;

import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import in.nareshit.raghu.model.UserDetailsImpl;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Component
public class JwtUtils {

@Value("${raghu.app.jwtSecret}")
private String jwtSecret;

@Value("${raghu.app.jwtExpTimeInMs}")
private int jwtExpTimeInMs;

public String generateToken(Authentication authentication)


{
UserDetailsImpl userDetails =
(UserDetailsImpl)authentication.getPrincipal();

return Jwts.builder()
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())

11 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
.setExpiration(new
Date(System.currentTimeMillis() + jwtExpTimeInMs))
.signWith(SignatureAlgorithm.HS512,
jwtSecret)
.compact()
;
}

public String getUsernameFromJwtToken(String token) {


return Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody()
.getSubject();
}

public boolean validateToken(String token) {


try {

Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token
);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

g. UserDetailsServiceImpl
package in.nareshit.raghu.service;

import org.springframework.beans.factory.annotation.Autowired;

12 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import
org.springframework.security.core.userdetails.UserDetails;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UsernameNotFoundEx
ception;
import org.springframework.stereotype.Service;

import in.nareshit.raghu.model.User;
import in.nareshit.raghu.model.UserDetailsImpl;
import in.nareshit.raghu.repo.UserRepository;

@Service
public class UserDetailsServiceImpl implements
UserDetailsService {

@Autowired
private UserRepository repository;

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException
{
//loading model class user object
User user = repository.findByUsername(username)
.orElseThrow(()->new
UsernameNotFoundException("User not exist" + username));
//converting into Spring Security User object
return UserDetailsImpl.build(user);
}

h. Authentication Entry Point


package in.nareshit.raghu.security;

import java.io.IOException;
13 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import
org.springframework.security.core.AuthenticationException;
import
org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

/**
* Logic is executed if login(JWT) failed
*/
@Component
public class AuthenticationEntryPointJwt implements
AuthenticationEntryPoint {

@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws
IOException, ServletException {

response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Unauthorized");

i. RestControllers
package in.nareshit.raghu.rest;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

14 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
@RestController
@RequestMapping("/home")
public class HomeRestController {

@GetMapping("/all")
public String allowAll() {
return "Permit All Data!";
}

@GetMapping("/user")
public String userData() {
return "User Data!";
}

@GetMapping("/mod")
public String moderatorData() {
return "Moderator Data!";
}

@GetMapping("/admin")
public String adminData() {
return "Admin Data!";
}

package in.nareshit.raghu.rest;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;

15 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import
org.springframework.security.authentication.AuthenticationManage
r;
import
org.springframework.security.authentication.UsernamePasswordAuth
enticationToken;
import org.springframework.security.core.Authentication;
import
org.springframework.security.core.context.SecurityContextHolder;
import
org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import in.nareshit.raghu.model.Role;
import in.nareshit.raghu.model.User;
import in.nareshit.raghu.model.UserDetailsImpl;
import in.nareshit.raghu.repo.UserRepository;
import in.nareshit.raghu.request.LoginRequest;
import in.nareshit.raghu.request.SignupRequest;
import in.nareshit.raghu.response.JwtResponse;
import in.nareshit.raghu.response.MessageResponse;
import in.nareshit.raghu.util.JwtUtils;
import in.nareshit.raghu.util.RolesUtils;

@RestController
@RequestMapping("/auth")
public class AuthenticationRestController {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private JwtUtils jwtUtils;

@Autowired
private UserRepository userRepository;

16 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

@Autowired
private RolesUtils rolesUtils;

@Autowired
private PasswordEncoder encoder;

//login
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(
@Valid @RequestBody LoginRequest loginRequest
)
{

// check for Authentication


Authentication authentication =
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()));

// set as SecurityContext(Authentication)

SecurityContextHolder.getContext().setAuthentication(authen
tication);

// Generate JWT Token


String jwt = jwtUtils.generateToken(authentication);

//current user object


UserDetailsImpl userDetails=
(UserDetailsImpl)authentication.getPrincipal();

// return response
return ResponseEntity.ok(
new JwtResponse(
jwt, //token
userDetails.getId(), //id

17 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
userDetails.getUsername(),
//username
userDetails.getEmail(), //email
userDetails.getAuthorities()
.stream()
.map(auth->auth.getAuthority())
.collect(Collectors.toSet())
//Set<String>
)
);
}

//register
@PostMapping("/register")
public ResponseEntity<?> createUser(
@Valid @RequestBody SignupRequest signupRequest
)
{
// check username exist

if(userRepository.existsByUsername(signupRequest.getUsernam
e())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error :
Username already exist"));
}
//check email exist

if(userRepository.existsByEmail(signupRequest.getEmail()))
{
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error :
EmailId already exist"));
}

//create user
User user = new User(

18 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
signupRequest.getUsername(),
signupRequest.getEmail(),
encoder.encode(signupRequest.getPassword())
);
//roles given by UI
Set<String> usrRoles = signupRequest.getRole();
//roles need to be stored in DB
Set<Role> dbRoles = new HashSet<>();

rolesUtils.mapRoles(usrRoles, dbRoles);
user.setRoles(dbRoles);
userRepository.save(user);

return ResponseEntity.ok(new MessageResponse("User


Created Successfully!"));
}

j. Security Filter
package in.nareshit.raghu.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.authentication.UsernamePasswordAuth
enticationToken;
19 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import
org.springframework.security.core.context.SecurityContextHolder;
import
org.springframework.security.core.userdetails.UserDetails;
import
org.springframework.security.web.authentication.WebAuthenticatio
nDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import in.nareshit.raghu.service.UserDetailsServiceImpl;
import in.nareshit.raghu.util.JwtUtils;

public class SecurityFilter extends OncePerRequestFilter {

@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;

protected void doFilterInternal(


HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException
{
try {
String jwt = readJwtToken(request);
if(jwt!=null && jwtUtils.validateToken(jwt)) {
String username =
jwtUtils.getUsernameFromJwtToken(jwt);
//load user object from db
UserDetails userDetails =
userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken
authentication =
new
UsernamePasswordAuthenticationToken(
userDetails,

20 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
null,

userDetails.getAuthorities()
);
authentication.setDetails(new
WebAuthenticationDetailsSource().buildDetails(request));

SecurityContextHolder.getContext().setAuthentication(authen
tication);
}
} catch (Exception e) {
e.printStackTrace();
}
filterChain.doFilter(request, response);

private String readJwtToken(HttpServletRequest request) {


String headerAuth = request.getHeader("Authorization");
if(StringUtils.hasText(headerAuth) &&
headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7,
headerAuth.length());
}
return null;
}

k. Security Config
package in.nareshit.raghu.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import
org.springframework.security.authentication.AuthenticationManage
r;

21 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import
org.springframework.security.config.annotation.authentication.bu
ilders.AuthenticationManagerBuilder;
import
org.springframework.security.config.annotation.web.builders.Http
Security;
import
org.springframework.security.config.annotation.web.configuration
.EnableWebSecurity;
import
org.springframework.security.config.annotation.web.configuration
.WebSecurityConfigurerAdapter;
import
org.springframework.security.config.http.SessionCreationPolicy;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder;
import
org.springframework.security.web.AuthenticationEntryPoint;
import
org.springframework.security.web.authentication.UsernamePassword
AuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import
org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import in.nareshit.raghu.filter.SecurityFilter;
import in.nareshit.raghu.service.UserDetailsServiceImpl;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{

@Autowired
private UserDetailsServiceImpl userDetailsService;

22 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;

@Bean
public SecurityFilter securityFilter() {
return new SecurityFilter();
}

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

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

protected void configure(AuthenticationManagerBuilder auth)


throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}

protected void configure(HttpSecurity http) throws


Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.antMatchers("/home/all").permitAll()

.antMatchers("/home/mod").hasAuthority("ROLE_MODERATOR")
.antMatchers("/home/admin").hasAuthority("ROLE_ADMIN")
.anyRequest().authenticated()

.and()

23 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)

.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;

http.addFilterBefore(securityFilter(),
UsernamePasswordAuthenticationFilter.class);
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",
new
CorsConfiguration().applyPermitDefaultValues());
return source;
}

Angular Application
ng new angular-spring-jwt

ng g class models/login-model --skipTests=true


ng g class models/user-model --skipTests=true
ng g class models/message-model --skipTests=true
ng g class models/jwt-model --skipTests=true

24 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
ng g s services/authentication --skipTests=true
ng g s services/token-storage --skipTests=true
ng g s services/user --skipTests=true

ng g c pages/login-page --skipTests=true
ng g c pages/register-page --skipTests=true
ng g c pages/home-page --skipTests=true
ng g c pages/profile-page --skipTests=true
ng g c pages/admin-page --skipTests=true
ng g c pages/moderator-page --skipTests=true
ng g c pages/user-page --skipTests=true

ng g interceptor security/auth --skipTests=true

a. models
export class UserModel {
constructor(
public username: String,
public email: String,
public password: String
) {

}
}

export class MessageModel {

constructor(public message:string) {

}
}

25 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

export class LoginModel {


constructor(
public username: String,
public password: String
) {

}
}

export class JwtModel {

constructor(
public token:string,
public type:string,
public id:number,
public username:string,
public email:string,
public roles:string[])
{

}
}

B. SERVICES
AuthenticationService.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { JwtModel } from '../models/jwt-model';
import { LoginModel } from '../models/login-model';
import { MessageModel } from '../models/message-model';

26 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import { UserModel } from '../models/user-model';

const baseUrl = 'http://localhost:9900/api/auth';

@Injectable({
providedIn: 'root',
})
export class AuthenticationService {
constructor(private http: HttpClient) {}

// register
registerUser(user: UserModel): Observable<MessageModel> {
return this.http.post<MessageModel>(`${baseUrl}/register`, u
ser);
}

// login
loginUser(login: LoginModel): Observable<JwtModel> {
return this.http.post<JwtModel>(`${baseUrl}/login`, login);
}
}

UserService.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

const baseUrl = 'http://localhost:9900/api/home';

@Injectable({
providedIn: 'root',
})
export class UserService {

27 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
constructor(private http: HttpClient) {}

getPublicContent(): Observable<any> {
return this.http.get(baseUrl + '/all', { responseType: 'text
' });
}

getUserData(): Observable<any> {
return this.http.get(baseUrl + '/user', { responseType: 'tex
t' });
}

getModeratorData(): Observable<any> {
return this.http.get(baseUrl + '/mod', { responseType: 'text
' });
}

getAdminData(): Observable<any> {
return this.http.get(baseUrl + '/admin', { responseType: 'te
xt' });
}
}

TokenStorageService.ts

import { Injectable } from '@angular/core';

const TOKEN_KEY = 'auth-token';


const USER_KEY = 'auth-user';

@Injectable({
providedIn: 'root',
})
export class TokenStorageService {

28 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
constructor() {}

signOut(): void {
window.sessionStorage.clear();
}

public saveToken(token: string): void {


window.sessionStorage.removeItem(TOKEN_KEY);
window.sessionStorage.setItem(TOKEN_KEY, token);
}

public getToken(): string | null {


return window.sessionStorage.getItem(TOKEN_KEY);
}

public saveUser(user: any): void {


window.sessionStorage.removeItem(USER_KEY);
window.sessionStorage.setItem(USER_KEY, JSON.stringify(user)
);
}

public getUser(): any {


const user = window.sessionStorage.getItem(USER_KEY);
if (user) {
return JSON.parse(user);
}

return {};
}
}

C. PAGES

RegisterPageComponent.ts

29 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import { Component, OnInit } from '@angular/core';
import { UserModel } from 'src/app/models/user-model';
import { AuthenticationService } from 'src/app/services/authenti
cation.service';

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

user: UserModel = new UserModel('', '', '');


isSuccessful: boolean = false;
message: string = '';

constructor(private auth: AuthenticationService) { }

ngOnInit(): void {
}

onSubmit() {
this.auth.registerUser(this.user).subscribe(
data => {
console.log(data);
this.isSuccessful = true;
this.message = data.message;
}, err => {
console.log(err);
this.isSuccessful = false;
this.message = err.error.message;
});
}

30 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}

RegisterPageComponent.html

<h3>User Register Form</h3>


<form
*ngIf="!isSuccessful"
name="form"
(ngSubmit)="registerForm.form.valid && onSubmit()"
#registerForm="ngForm"
>
<div class="form-group">
<label for="username">Username</label>
<input
type="text"
class="form-control"
name="username"
[(ngModel)]="user.username"
required
minlength="3"
maxlength="20"
#username="ngModel"
/>
<div
class="alert-danger"
*ngIf="username.errors && (username.touched || registerFor
m.submitted)"
>
<div *ngIf="username.errors.required">Username is required
</div>
<div *ngIf="username.errors.minlength">
Username must be at least 3 characters
</div>
<div *ngIf="username.errors.maxlength">

31 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
Username must be at most 20 characters
</div>
</div>
</div>

<div class="form-group">
<label for="email">Email</label>
<input
type="email"
class="form-control"
name="email"
[(ngModel)]="user.email"
required
email
#email="ngModel"
/>
<div
class="alert-danger"
*ngIf="email.invalid && (email.touched || registerForm.sub
mitted)"
>
<div *ngIf="email.errors?.required">Email is required</div
>
<div *ngIf="email.errors?.email">Email must be a valid ema
il address</div>
</div>
</div>

<div class="form-group">
<label for="password">Password</label>
<input
type="password"
class="form-control"
name="password"

32 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
[(ngModel)]="user.password"
required
minlength="6"
#password="ngModel"
/>
<div
class="alert-danger"
*ngIf="password.invalid && (password.touched || registerFo
rm.submitted)"
>
<div *ngIf="password.errors?.required">Password is require
d</div>
<div *ngIf="password.errors?.minlength">
Password must be at least 6 characters
</div>
</div>
</div>

<div class="form-group">
<button [disabled]="!registerForm.form.valid" class="btn btn
-success btn-block">Sign Up</button>
</div>

<div
class="alert alert-warning"
*ngIf="registerForm.submitted && !isSuccessful && message !=
''"
>
{{ message }}
</div>
</form>

<div class="alert alert-success" *ngIf="isSuccessful">


{{ message }}

33 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
</div>

LoginPageComponent.ts

import { Component, OnInit } from '@angular/core';


import { LoginModel } from 'src/app/models/login-model';
import { AuthenticationService } from 'src/app/services/authenti
cation.service';
import { TokenStorageService } from 'src/app/services/token-
storage.service';

@Component({
selector: 'app-login-page',
templateUrl: './login-page.component.html',
styleUrls: ['./login-page.component.css'],
})
export class LoginPageComponent implements OnInit {
//------variables----------------------
isLoggedIn = false;
isLoginFailed = false;
errorMessage = '';
roles: string[] = [];
loginModel : LoginModel = new LoginModel('','');
//---------DI-------------------
constructor(
private authService: AuthenticationService,
private tokenStorage: TokenStorageService
) {}
//---------OnInit-------------------
ngOnInit(): void {
if (this.tokenStorage.getToken()) {
this.isLoggedIn = true;
this.roles = this.tokenStorage.getUser().roles;

34 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}
}

onSubmit(): void {

this.authService.loginUser(this.loginModel).subscribe(
data => {
this.tokenStorage.saveToken(data.token);
this.tokenStorage.saveUser(data);

this.isLoginFailed = false;
this.isLoggedIn = true;
this.roles = this.tokenStorage.getUser().roles;
this.reloadPage();
},
err => {
this.errorMessage = err.error.message;
this.isLoginFailed = true;
}
);
}

reloadPage(): void {
window.location.reload();
}
}

LoginPageComponent.html
<h3>User Login Form</h3>
<form
*ngIf="!isLoggedIn"
name="form"
(ngSubmit)="loginForm.form.valid && onSubmit()"
#loginForm="ngForm"

35 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
>
<div class="form-group">
<label for="username">Username</label>
<input
type="text"
class="form-control"
name="username"
[(ngModel)]="loginModel.username"
required
#username="ngModel"
/>
<div
class="alert alert-danger"
role="alert"
*ngIf="username.errors && (username.touched || loginForm.s
ubmitted)"
>
Username is required!
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
class="form-control"
name="password"
[(ngModel)]="loginModel.password"
required
minlength="6"
#password="ngModel"
/>
<div
class="alert alert-danger"
role="alert"

36 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
*ngIf="password.errors && (password.touched || loginForm.s
ubmitted)"
>
<div *ngIf="password.errors.required">Password is required
</div>
<div *ngIf="password.errors.minlength">
Password must be at least 6 characters
</div>
</div>
</div>
<div class="form-group">
<button [disabled]="!loginForm.form.valid" class="btn btn-
success btn-block">Login</button>
</div>
<div class="form-group">
<div
class="alert alert-danger"
role="alert"
*ngIf="loginForm.submitted && isLoginFailed"
>
Login failed: {{ errorMessage }}
</div>
</div>
</form>

<div class="alert alert-success" *ngIf="isLoggedIn">


Logged in as {{ roles }}.
</div>

HomePageComponent.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';

@Component({

37 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css'],
})
export class HomePageComponent implements OnInit {
content?: string;

constructor(private userService: UserService) {}

ngOnInit(): void {
this.userService.getPublicContent().subscribe(
(data) => {
this.content = data;
},
(err) => {
console.log(err);
}
);
}
}

HomePageComponent.html
<div class="container">
<header class="jumbotron">
<p>{{ content }}</p>
</header>
</div>

ProfilePageComponent.ts

import { Component, OnInit } from '@angular/core';


import { TokenStorageService } from 'src/app/services/token-
storage.service';

38 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
@Component({
selector: 'app-profile-page',
templateUrl: './profile-page.component.html',
styleUrls: ['./profile-page.component.css']
})
export class ProfilePageComponent implements OnInit {

currentUser: any;

constructor(private token: TokenStorageService) { }

ngOnInit(): void {
this.currentUser = this.token.getUser();
}

ProfilePageComponent.html
<div class="container" *ngIf="currentUser; else loggedOut">
<header class="jumbotron">
<h3>
<strong>{{ currentUser.username }}</strong> Profile
</h3>
</header>
<p>
<strong>Token:</strong>
{{ currentUser.token.substring(0, 20) }} ...
{{ currentUser.token.substr(currentUser.token.length -
20) }}
</p>
<p>
<strong>Email:</strong>
{{ currentUser.email }}
</p>

39 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
<strong>Roles:</strong>
<ul>
<li *ngFor="let role of currentUser.roles">
{{ role }}
</li>
</ul>
</div>

<ng-template #loggedOut> Please login. </ng-template>

UserPageComponent.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';

@Component({
selector: 'app-user-page',
templateUrl: './user-page.component.html',
styleUrls: ['./user-page.component.css']
})
export class UserPageComponent implements OnInit {
content?: string;

constructor(private userService: UserService) { }

ngOnInit(): void {
this.userService.getUserData().subscribe(
data => {
this.content = data;
},
err => {
console.log(err);
}
);

40 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}

UserPageComponent.ts
<div class="container">
<header class="jumbotron">
<p>{{ content }}</p>
</header>
</div>

AdminPageComponent.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';

@Component({
selector: 'app-admin-page',
templateUrl: './admin-page.component.html',
styleUrls: ['./admin-page.component.css'],
})
export class AdminPageComponent implements OnInit {
content?: string;

constructor(private userService: UserService) {}

ngOnInit(): void {
this.userService.getAdminData().subscribe(
(data) => {
this.content = data;
},
(err) => {
console.log(err);

41 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
}
);
}
}

AdminPageComponent.html
<div class="container">
<header class="jumbotron">
<p>{{ content }}</p>
</header>
</div>

ModeratorPageComponent.ts

import { Component, OnInit } from '@angular/core';


import { UserService } from 'src/app/services/user.service';

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

content?: string;

constructor(private userService: UserService) { }

ngOnInit(): void {
this.userService.getModeratorData().subscribe(
data => {
this.content = data;
},
err => {

42 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
console.log(err);
}
);
}

ModeratorPageComponent.html
<div class="container">
<header class="jumbotron">
<p>{{ content }}</p>
</header>
</div>

d. Security Interceptor
AuthInterceptor.ts

import { Injectable } from '@angular/core';


import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HTTP_INTERCEPTORS,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { TokenStorageService } from '../services/token-
storage.service';

const TOKEN_HEADER_KEY = 'Authorization';

43 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
//inject token service
constructor(private tokenService: TokenStorageService) {}

intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let authReq = request;
const token = this.tokenService.getToken();
if (token != null) {
authReq = request.clone({
headers: request.headers.set(TOKEN_HEADER_KEY, 'Bearer '
+ token),
});
}
return next.handle(authReq);
}
}

export const authInterceptorProviders = [


{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi
: true },
];

AppRouting.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminPageComponent } from './pages/admin-page/admin-
page.component';
import { HomePageComponent } from './pages/home-page/home-
page.component';

44 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import { LoginPageComponent } from './pages/login-page/login-
page.component';
import { ModeratorPageComponent } from './pages/moderator-
page/moderator-page.component';
import { ProfilePageComponent } from './pages/profile-
page/profile-page.component';
import { RegisterPageComponent } from './pages/register-
page/register-page.component';
import { UserPageComponent } from './pages/user-page/user-
page.component';

const routes: Routes = [


{ path: 'home', component: HomePageComponent },
{ path: 'login', component: LoginPageComponent },
{ path: 'register', component: RegisterPageComponent },
{ path: 'profile', component: ProfilePageComponent },
{ path: 'user', component: UserPageComponent },
{ path: 'mod', component: ModeratorPageComponent },
{ path: 'admin', component: AdminPageComponent },
{ path: '', redirectTo: 'home', pathMatch: 'full' },
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}

AppComponent.html
<div id="app">
<nav class="navbar navbar-expand navbar navbar-dark bg-
primary">
<a href="#" class="navbar-brand">NareshIT</a>
<ul class="navbar-nav mr-auto" routerLinkActive="active">

45 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
<li class="nav-item">
<a href="/home" class="nav-link text-
white" routerLink="home">Home </a>
</li>
<li class="nav-item" *ngIf="showAdminPage">
<a href="/admin" class="nav-link text-
white" routerLink="admin">Admin</a>
</li>
<li class="nav-item" *ngIf="showModeratorPage">
<a href="/mod" class="nav-link text-
white" routerLink="mod">Moderator</a>
</li>
<li class="nav-item">
<a href="/user" class="nav-link text-
white" *ngIf="isLoggedIn" routerLink="user">User</a>
</li>
</ul>

<ul class="navbar-nav ml-auto" *ngIf="!isLoggedIn">


<li class="nav-item">
<a href="/register" class="nav-link text-
white" routerLink="register">Sign Up</a>
</li>
<li class="nav-item">
<a href="/login" class="nav-link text-
white" routerLink="login">Login</a>
</li>
</ul>

<ul class="navbar-nav ml-auto" *ngIf="isLoggedIn">


<li class="nav-item">
<a href="/profile" class="nav-link text-
white" routerLink="profile">{{ username }}</a>
</li>

46 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
<li class="nav-item">
<a href class="nav-link text-
white" (click)="logout()">LogOut</a>
</li>
</ul>
</nav>

<div class="container">
<router-outlet></router-outlet>
</div>
</div>

import { Component } from '@angular/core';


import { TokenStorageService } from './services/token-
storage.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
private roles: string[] = [];
isLoggedIn = false;
showAdminPage = false;
showModeratorPage = false;
username?: string;

constructor(private tokenStorageService: TokenStorageService)


{}

ngOnInit(): void {
this.isLoggedIn = !!this.tokenStorageService.getToken();

47 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]

if (this.isLoggedIn) {
const user = this.tokenStorageService.getUser();
this.roles = user.roles;

this.showAdminPage = this.roles.includes('ROLE_ADMIN');
this.showModeratorPage = this.roles.includes('ROLE_MODERAT
OR');

this.username = user.username;
}
}

logout(): void {
this.tokenStorageService.signOut();
window.location.reload();
}
}

import { NgModule } from '@angular/core';


import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';


import { AppComponent } from './app.component';
import { LoginPageComponent } from './pages/login-page/login-
page.component';
import { RegisterPageComponent } from './pages/register-
page/register-page.component';
import { HomePageComponent } from './pages/home-page/home-
page.component';
import { ProfilePageComponent } from './pages/profile-
page/profile-page.component';
import { AdminPageComponent } from './pages/admin-page/admin-
page.component';

48 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
import { ModeratorPageComponent } from './pages/moderator-
page/moderator-page.component';
import { UserPageComponent } from './pages/user-page/user-
page.component';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { authInterceptorProviders } from './security/auth.interc
eptor';

@NgModule({
declarations: [
AppComponent,
LoginPageComponent,
RegisterPageComponent,
HomePageComponent,
ProfilePageComponent,
AdminPageComponent,
ModeratorPageComponent,
UserPageComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [authInterceptorProviders],
bootstrap: [AppComponent]
})
export class AppModule { }

index.html
<!doctype html>

49 | P a g e
RAGHU SIR [NARESH i TECHNOLOGIES, AMEERPET, HYDERABAD]
<html lang="en">

<head>
<meta charset="utf-8">
<title>Angularjwtapp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-
scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/b
ootstrap/4.0.0/css/bootstrap.min.css"
>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/
1.12.9/umd/popper.min.js"

crossorigin></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/j
s/bootstrap.min.js"

> </script>
</head>

<body>
<div class="container">
<app-root></app-root>
</div>
</body>

</html>

50 | P a g e

You might also like