JWT (Java Web Token)
A compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS)structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.
JWT Basic Steps
1. A user logs into an application and provides their credentials.
2. The Authentication server authenticates the user and creates a JWT which is returned to the user.
3. The user then makes various calls to the application and passes with these calls the newly created JWT.
4 .The application can use the JWT to verify that the user has in fact been authenticated and proceed with fulfilling the users’ requests.
Directory Structure of JWT Application
JWT(JSON Web Token) and Spring Security Config classes
SpingAPISecurityConfig.java
package in.jk.springboot.configuaration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import in.jk.springboot.jwt.JwtAuthenicationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpingAPISecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenicationFilter jwtAuthFilter;
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/jwt/authenticate/**").hasAnyAuthority("USER","ADMIN")
.and().authorizeRequests().antMatchers("/productapi/**")
.hasAnyAuthority("ADMIN").
and().httpBasic();
httpSecurity.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authManager) throws Exception {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
authManager.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
UserDetailServiceImpl.java
package in.jk.springboot.configuaration;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import in.jk.springboot.entity.UserEntity;
import in.jk.springboot.repository.UserRepository;
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
private UserDetails userDetails;
@Override
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException {
List<UserEntity> userEntityList = userRepository.findUserByUserName(userName);
if (!userEntityList.isEmpty()) {
UserEntity userEntity = userEntityList.get(0);
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(userEntity.getRole());
userDetails = new User(userEntity.getUserName(), userEntity.getPassword(),
Arrays.asList(grantedAuthority));
System.out.println("grantedAuthorizeUser :: " + userDetails);
} else {
System.out.println("User Not Present ");
}
return userDetails;
}
public UserDetails getUserDetails() {
return userDetails;
}
public void setUserDetails(UserDetails userDetails) {
this.userDetails = userDetails;
}
}
JwtUtils.java
package in.jk.springboot.jwt;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@Component
public class JwtUtils implements Serializable {
private static final long serialVersionUID = 1L;
private static long JWT_TOKEN_VALIDITY=5*60*60;
private String secret="jwt_token";
//retrieve username from jwt token
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
//retrieve expiration date from jwt token
public Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
//for retrieveing any information from token we will need the secret key
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
//check if the token has expired
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
//generate token for user
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername());
}
//while creating the token -
//1. Define claims of the token, like Issuer, Expiration, Subject, and the ID
//2. Sign the JWT using the HS512 algorithm and secret key.
//3. According to JWS Compact Serialization(https://tools.ietf.org/html/draft-ietf-jose-json- web-signature-41#section-3.1)
// compaction of the JWT to a URL-safe string
private String doGenerateToken(Map<String, Object> claims, String subject) {
return Jwts.builder().setClaims(claims).setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
.signWith(SignatureAlgorithm.HS512, secret).compact();
}
//validate token
public Boolean validateToken(String token, UserDetails userDetails) {
final String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}
JwtAuthenticationController.java
package in.jk.springboot.jwt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import in.jk.springboot.configuaration.UserDetailServiceImpl;
import in.jk.springboot.response.Response;
@RestController
@RequestMapping("/jwt")
public class JwtAuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailServiceImpl userDetailService;
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public Response getAuthenticationToken(@RequestBody JwtTokenRequest jwtTokenRequest) {
System.out.println("Authenicate Controller ...");
Response response = null;
JwtTokenResponse jwtTokenResponse = null;
response = new Response();
jwtTokenResponse = new JwtTokenResponse();
try {
if (authenticate(jwtTokenRequest.getUserName(), jwtTokenRequest.getPassword())) {
UserDetails userDetails =
userDetailService.loadUserByUsername(jwtTokenRequest.getUserName());
final String token = jwtUtils.generateToken(userDetails);
System.out.println("Generated Token ::"+token);
jwtTokenResponse = new JwtTokenResponse();
jwtTokenResponse.setUserName(jwtTokenRequest.getUserName());
jwtTokenResponse.setToken(token);
response.setResponse("200", "Authentication Token", jwtTokenResponse, "");
}
} catch (Exception e) {
jwtTokenResponse = new JwtTokenResponse();
jwtTokenResponse.setUserName(jwtTokenRequest.getUserName());
jwtTokenResponse.setToken("Error in Token Generation ");
response.setResponse("500", "Error in Token Generation",
jwtTokenResponse, e.getMessage());
}
return response;
}
private boolean authenticate(String userName, String password) throws Exception {
boolean status = Boolean.FALSE;
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userName,
password);
try {
Authentication auth = authenticationManager.authenticate(authentication);
status = auth.isAuthenticated();
System.out.println("Authentication Status :: "+status);
}
catch (DisabledException e) {
throw new Exception("User Disabled ", e);
}
catch (BadCredentialsException e) {
throw new Exception("User Disabled ", e);
} catch (Exception e) {
throw new Exception(e);
}
return status;
}
}
JwtAuthenicationFilter.java
package in.jk.springboot.jwt;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
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.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import in.jk.springboot.configuaration.UserDetailServiceImpl;
import io.jsonwebtoken.ExpiredJwtException;
@Component
public class JwtAuthenicationFilter extends OncePerRequestFilter {
@Autowired
private UserDetailServiceImpl UserDetailService;
@Autowired
private JwtUtils jwtUtils;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,FilterChain filterChain)
throws ServletException, IOException {
String userName = null;
String jwtToken = null;
TokenError tokenError =null;
String jwtTokenHeader = request.getHeader("Authorization");
String isAuthorizationRequired = request.getHeader("IsAuthorizationRequired");
RequestDispatcher dispatcher = request.getRequestDispatcher("/errorapi/error");
StringBuffer url =request.getRequestURL();
System.out.println("Request URL :: "+url);
System.out.println("Token :: "+jwtTokenHeader);
System.out.println("IsAuthorizationRequired :: "+isAuthorizationRequired);
if (jwtTokenHeader != null && jwtTokenHeader.startsWith("jwt ")) {
jwtToken = jwtTokenHeader.replace("jwt ", "");
System.out.println("Token :: "+jwtToken);
try {
userName = jwtUtils.getUsernameFromToken(jwtToken);
}
catch (ExpiredJwtException e) {
System.out.println("Token Expired :: " + e);
tokenError =new TokenError();
tokenError.setToken(jwtToken);
tokenError.setUserName(userName);
tokenError.setTokenErrorType("Token Expire :: "+e.getMessage());
request.setAttribute("tokenError", tokenError);
dispatcher.forward(request, response);
return;
} catch (Exception e) {
System.out.println("Error in Token :: " + e);
tokenError =new TokenError();
tokenError.setToken(jwtToken);
tokenError.setUserName(userName);
tokenError.setTokenErrorType("Error in Token :: "+e.getMessage());
request.setAttribute("tokenError", tokenError);
dispatcher.forward(request, response);
return;
}
} else {
if(isAuthorizationRequired==null || "Y".equals(isAuthorizationRequired) ) {
System.out.println("Request Without Token :: Token Required for Authorization");
}
else {
System.out.println("Request Without Token :: Token Not Required ");
}
}
if(userName!=null && SecurityContextHolder.getContext().getAuthentication()==null )
{
UserDetails userDetails = UserDetailService.loadUserByUsername(userName);
System.out.println("UserDetails :: "+userDetails);
if(jwtUtils.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=null;
usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails,
null,userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext()
.setAuthentication(usernamePasswordAuthenticationToken);
}
}
try {
filterChain.doFilter(request, response);
}catch(Exception e) {
System.out.println(e);
}
}
}
JwtTokenRequest.java
package in.jk.springboot.jwt;
public class JwtTokenRequest {
private String userName;
private String password;
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;
}
@Override
public String toString() {
return "JwtRequest [userName=" + userName + ", password=" + password + "]";
}
}
JwtTokenResponse.java
package in.jk.springboot.jwt;
public class JwtTokenResponse {
private String userName;
private String token;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "JwtTokenResponse [userName=" + userName + ", token=" + token + "]";
}
}
TokenError.java
package in.jk.springboot.jwt;
public class TokenError {
private String userName;
private String token;
private String tokenErrorType;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getTokenErrorType() {
return tokenErrorType;
}
public void setTokenErrorType(String tokenErrorType) {
this.tokenErrorType = tokenErrorType;
}
@Override
public String toString() {
return "TokenError [userName=" + userName + ", token=" + token + ",
tokenErrorType=" + tokenErrorType + "]";
}
}
SwaggerConfig.java
package in.jk.springboot.configuaration;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
//Adding Header
ParameterBuilder authorizationParameterBuilder = new ParameterBuilder();
authorizationParameterBuilder.name("Authorization")
.modelRef(new ModelRef("string")).parameterType("header").required(false)
.description("Enter Token ").build();
ParameterBuilder isauthorizationRequiredBuilder = new ParameterBuilder();
isauthorizationRequiredBuilder.name("IsAuthorizationRequired")
.modelRef(new ModelRef("string")).parameterType("header").required(true)
.description("Enter Y or N ").build();
List<Parameter> aParameters = new ArrayList<Parameter>();
aParameters.add(authorizationParameterBuilder.build());
aParameters.add(isauthorizationRequiredBuilder.build());
return new Docket(DocumentationType.SPRING_WEB)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build().pathMapping("").globalOperationParameters(aParameters);
}
}
JWT application Request POJO classes
EmployeeRequest.java
package in.jk.springboot.request;
public class EmployeeRequest {
private int empId;
private String name;
private String company;
//Getters and Setters
@Override
public String toString() {
return "Employee [empId=" + empId + ", name=" + name + ", company=" + company + "]";
}
}
UserRequest .java
package in.jk.springboot.request;
public class UserRequest {
private int userId;
private String name;
private String userName;
private String password;
private String role;
//Getters and Setters
@Override
public String toString() {
return "UserRequest [userId=" + userId + ", name=" + name + ", userName=" + userName + ", password=" + password
+ ", role=" + role + "]";
}
}
Jwt application service interface
UserService.java
package in.jk.springboot.service;
import in.jk.springboot.request.UserRequest;
import in.jk.springboot.response.Response;
public interface UserService {
public Response findUserByUserId(Integer userId);
public Response addUser(UserRequest userRequest);
public Response findUserByUserName(String userName);
}
EmployeeService.java
package in.jk.springboot.service;
import in.jk.springboot.request.EmployeeRequest;
import in.jk.springboot.response.Response;
public interface EmployeeService {
public Response findEmployeeById(Integer empId);
public Response addEmployee(EmployeeRequest employeeRequest);
}
JWT application service interface implementation
EmployeeServiceImpl.java
package in.jk.springboot.serivce.impl;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import in.jk.springboot.entity.Employee;
import in.jk.springboot.repository.EmployeeRespository;
import in.jk.springboot.request.EmployeeRequest;
import in.jk.springboot.response.Response;
import in.jk.springboot.service.EmployeeService;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
EmployeeRespository employeeRespository;
public Response findEmployeeById(Integer empId) {
Response response = null;
Object responseData=null;
response = new Response();
try {
Employee employee = employeeRespository.getOne(empId);
System.out.println(employee);
responseData =employee;
response.setResponse("200", "Request Successfull.", responseData, null);
} catch (Exception e) {
response.setResponse("400", "Request UnSuccessfull.", null, e.getMessage());
}
return response;
}
@Override
public Response addEmployee(EmployeeRequest employeeRequest) {
Response response = null;
Employee employee = new Employee();
employee.setEmpId(employeeRequest.getEmpId());
employee.setName(employeeRequest.getName());
employee.setCompany(employeeRequest.getCompany());
response = new Response();
try {
Employee employeeEnity = employeeRespository.save(employee);
System.out.println(employeeEnity);
Map<String,Object> responseMap = new HashMap<String,Object>();
responseMap.put("employee", employeeEnity);
response.setResponse("200", "Request Successfull.", responseMap, null);
} catch (Exception e) {
response.setResponse("200", "Request Successfull.", employee, null);
}
return response;
}
}
UserServiceImpl.java
package in.jk.springboot.serivce.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import in.jk.springboot.entity.UserEntity;
import in.jk.springboot.repository.UserRepository;
import in.jk.springboot.request.UserRequest;
import in.jk.springboot.response.Response;
import in.jk.springboot.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public Response findUserByUserId(Integer userId) {
Response response = null;
Object responseData = null;
response = new Response();
try {
UserEntity userEntity = userRepository.getOne(userId);
System.out.println(userEntity);
responseData = userEntity;
response.setResponse("200", "Request Successfull.", responseData, null);
} catch (Exception e) {
response.setResponse("400", "Request UnSuccessfull.", null, e.getMessage());
}
return response;
}
@Override
public Response addUser(UserRequest userRequest) {
Response response = null;
Object responseData = null;
response = new Response();
try {
UserEntity userEntity = new UserEntity();
userEntity.setUserId(userRequest.getUserId());
userEntity.setName(userRequest.getName());
userEntity.setUserName(userRequest.getUserName());
userEntity.setRole(userRequest.getRole());
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = passwordEncoder.encode(userRequest.getPassword());
userEntity.setPassword(password);
userEntity = userRepository.save(userEntity);
System.out.println(userEntity);
responseData = userEntity;
response.setResponse("200", "User Saved Successfull.", responseData, null);
} catch (Exception e) {
response.setResponse("400", "User Saved Request Unsuccessfull.",
null, e.getMessage());
}
return response;
}
@Override
public Response findUserByUserName(String userName) {
Response response = null;
Object responseData = null;
List<UserEntity> userList = null;
response = new Response();
try {
userList = userRepository.findUserByUserName(userName);
if (!userList.isEmpty()) {
UserEntity userEntity = userList.get(0);
System.out.println(userEntity);
responseData = userEntity;
}
response.setResponse("200", "Request Successfull.", responseData, null);
} catch (Exception e) {
response.setResponse("400", "Request UnSuccessfull.", null, e.getMessage());
}
return response;
}
}
JWT applicaton Entity class
Employee.java
package in.jk.springboot.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="jwt_employee_details")
public class Employee {
@Id
@Column(name="emp_id")
private int empId;
@Column(name="name")
private String name;
@Column(name="company")
private String company;
//Getters and Setters
}
UserEntity.java
package in.jk.springboot.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="jwt_user")
public class UserEntity {
@Id
@Column(name="user_id")
private Integer userId;
@Column(name="user_name" ,unique = true)
private String userName;
@Column(name="name")
private String name;
@Column(name="password")
private String password;
@Column(name="email_id")
private String emailId;
@Column(name="role")
private String role;
//Getters and Setters
}
JWT Application Repository
UserRepository.java
package in.jk.springboot.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import in.jk.springboot.entity.UserEntity;
public interface UserRepository extends JpaRepository<UserEntity, Integer> {
@Query("From UserEntity user where user.userName=:userName")
public List<UserEntity> findUserByUserName(@Param("userName") String userName);
}
EmployeeRespository .java
package in.jk.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import in.jk.springboot.entity.Employee;
public interface EmployeeRespository extends JpaRepository<Employee, Integer> {
}
Response class
Response .java
package in.jk.springboot.response;
public class Response {
private String responseCode;
private String responseMessage;
private Object responseData;
private String errorMessage;
public void setResponse(String responseCode, String responseMessage, Object responseData, String errorMessage) {
this.setResponseCode(responseCode);
this.setResponseMessage(responseMessage);
this.setResponseData(responseData);
this.setErrorMessage(errorMessage);
}
public String getResponseCode() {
return responseCode;
}
public void setResponseCode(String responseCode) {
this.responseCode = responseCode;
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public Object getResponseData() {
return responseData;
}
public void setResponseData(Object responseData) {
this.responseData = responseData;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
JWT Application Controller class
package in.jk.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import in.jk.springboot.request.EmployeeRequest;
import in.jk.springboot.response.Response;
import in.jk.springboot.service.EmployeeService;
@CrossOrigin
@RestController
@RequestMapping("/adminapi")
public class AdminController {
@Autowired
EmployeeService employeeService;
@RequestMapping(value = "/employee/{empId}" , produces = "application/json",
method = RequestMethod.GET)
public Response findEmployeeById(@PathVariable Integer empId) {
return employeeService.findEmployeeById(empId);
}
@RequestMapping(value = "/employee" , produces = "application/json",
method = RequestMethod.POST)
public Response addEmployee(@RequestBody EmployeeRequest employeeRequest) {
return employeeService.addEmployee(employeeRequest);
}
}
UserController.java
package in.jk.springboot.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import in.jk.springboot.request.UserRequest;
import in.jk.springboot.response.Response;
import in.jk.springboot.service.UserService;
@CrossOrigin
@RestController
@RequestMapping("/userapi")
public class UserController {
@Autowired
UserService userService;
@Autowired
HttpServletRequest httpServletRequest;
@RequestMapping(value = "/findUserByUserId/{userId}", produces = "application/json",
method = RequestMethod.GET)
public Response findUserByUserId(@PathVariable Integer userId) {
return userService.findUserByUserId(userId);
}
@RequestMapping(value = "/addUser", produces = "application/json", method = RequestMethod.POST)
public Response addUser(@RequestBody UserRequest userRequest) {
return userService.addUser(userRequest);
}
}
ErrorController.java
package in.jk.springboot.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import in.jk.springboot.jwt.TokenError;
import in.jk.springboot.response.Response;
@CrossOrigin
@RestController
@RequestMapping("/errorapi")
public class ErrorController {
@Autowired
HttpServletRequest httpServletRequest;
@RequestMapping(value = "/error", produces = "application/json",
method = {RequestMethod.GET,RequestMethod.POST})
public Response tokenError() {
System.out.println("Error in token Authorization");
Response response = new Response();
TokenError tokenError = (TokenError) httpServletRequest.getAttribute("tokenError");
response.setResponse("500", "Token Error ", tokenError, "Error in Token");
return response;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.jk</groupId>
<artifactId>springbootjwt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootWithJWT</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT Dependency -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Swagger Dependency -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
For Database configuration we have Postgress database .
spring.datasource.url =jdbc:postgresql://localhost:5432/postgres
SET SQL_SAFE_UPDATES = 0;
spring.datasource.username=postgres
spring.datasource.password=jk123
spring.datasource.driverClassName=org.postgresql.Driver
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLPostgresSQLDialect
#spring.jpa.show-sql=true
spring.jpa.show-sql = true
#ddl2auto commannd
spring.jpa.hibernate.ddl-auto = update
spring.jackson.serialization.fail-on-empty-beans=false
JWT Application Starter class
package in.jk.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
System.out.println("Spring Application Started ........... ");
}
}
For JWT Application Testing First Start the Application using SpringbootApplication class
1 . Open the Browser then type the follwing url Swagger API Tool.
http://localhost:8080/swagger-ui.html
For each Service in this application you require two header parameter
IsAuthorizationRequired :- This Header parameter is used enbale and disable toekn based authorization .
IsAuthorizationRequired takes two value
Y:- To Enable Autorization
N:- To Disable Autorization
Authorization :- This Header parameter takes local computed toekn string if IsAuthorizationRequired value Y otherwise it have no value or blank .
Note : - In Order to compute string localy in this application we have add jwt in prifix of token string response by token service
Local computed Token String = jwt+" " +token String ;
Example
Authorization": "jwt eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqb2huIiwiZXhwIjoxN
2. For Getting Token First we need to add a User with user service so open user service the add one user following user details
Header Paramter Value
Authorization :- No value
IsAuthorizationRequired :- N
User Name = John
userId = john
password = john
role = ADMIN
Add User Service
3. For Getting Token Open Authenticate Service enter userName and password of added user .
Header Paramter Value
Authorization :- No value
IsAuthorizationRequired :- N
Authenticate Service Token Request
Authenticate Service Token Response
4 . Now finally to Test Token authorization open Employee Service
To Calling Add Employee enter header parameter like following
Header Paramter example Value
Authorization :- jwt+" "+ token retrive from Authenticate Service Token Request
IsAuthorizationRequired :- Y
Add Employee Service Request
Add Employee Service Response
5. Find Employee Service with valid token
6. Find Employee Service with invalid token
This is how we can used JWT(JSON Web Token) with Spring Secuirty in Springboot .
please comment if you find any mistake .
No comments:
Post a Comment