https://github.com/ibrahimcseku/jwt
This is the diagram which we will implement in this article. We will prepare a spring boot application with role based JWT authentication. JWT authentication is very simple, it follows some basic steps:
- ü Client completes the registration
process from an identity provider.
- ü Then client will send a request with
valid credential to the identity provider. Identity provider verifies the
credentials and if it is ok then it provide an encrypted token (JWT).
- ü Client stores the token (JWT) for a
specified period of time depending on the expiration time set by the identity
provider.
- ü Then clients send the stored token
(JWT) with the authorization header for every request to access the provider
services.
- ü For each request, the service
provider takes the token (JWT) from the Authorization header and decrypts it.
Then validates the signature and extracts the user data, check the permissions
and if everything is OK then it accept the request. Here identity provider and
service provider should have an agreement on secret key to decrypt the token.
After importing the project, you might face some error
related with maven dependency. To resolve this error, replace the properties tag with below code in pom.xml file:
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
Now include the following dependency in pom.xml file for JWT:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
After completing the above step, select the project and right click on it and go to Maven > Update project.. from eclipse menu option.
Before writing any code we will configure the data source for
mysql database and JWT configuration in Application.properties file:
jwt.signing.key.secret=mySecret
jwt.token.expiration.in.seconds=1800
spring.datasource.username=username
spring.datasource.password =password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
Database table Creation:
CREATE TABLE users (
id
int,
username varchar(56),
password
varchar(256),
PRIMARY KEY (id)
userid int,
roleid int,
PRIMARY
KEY (userid,roleid)
);
id int,
name
varchar(56),
PRIMARY
KEY (id)
);
INSERT INTO roles(id,name) VALUES (3,'ROLE_ADMIN');
Table
users will store the registered
user information, table roles will
store the roles entry and user_roles
table will store the user and role id as a foreign key.
Now we will create entity class to persist the data for users, roles and user_roles table into the package com.implementation.jwt.model
Role.java
package com.implementation.jwt.model;
import javax.persistence.Column;
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;
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Enumerated(EnumType.STRING)
@Column(length = 20)
private RoleEnum name;
public Role() {
}
public Role(RoleEnum name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public RoleEnum getName() {
return name;
}
public void setName(RoleEnum name) {
this.name = name;
}
}
For
users and user_roles create User.java
package com.implementation.jwt.model;
import java.util.HashSet;
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;
@Entity
@Table(name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = "username") })
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String username;
private String password;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "user_roles", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "roleid"))
private Set<Role> roles = new HashSet<>();
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
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 Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Now we need to know our purpose because it will help us to generate the request and response data model. We will create below API’s:
For user
registration:
Method:POST
Conten-Type: application/json
Body sample:
{
"username":"Sara",
"password":"12345",
"role":["admin"]
}
Response sample: { "message": " Registration successfully! " }
URL: http://localhost:8080/api/authenticate/login
Method:POST
Conten-Type: application/json
Body sample:
{
"username":"Sara",
"password":"12345"
}
Response sample:
{
"id": 19,
"username": "Sara",
"roles": [
"ROLE_ADMIN"
],
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJTYXJhIiwiaWF0IjoxNjE1NjM0NjU3LCJleHAiOjE2MTU2MzY0NTd9.Tz8zS4qRziyZOLi01xRjDLW28yljx7JPgU9qhboSrvJ_4dtaXf9i5SJtJDcZIoxgWKFCcExyCieLAlAPAhNrDA"
}
To check the role and token based accessibility we create some GET API:
a. http://localhost:8080/api/resource/content
b. http://localhost:8080/api/resource/user
c. http://localhost:8080/api/resource/admin
Now according to the API requirements we will create some data model for request and response inside the package com.implementation.jwt.model
RegistrationRequest.java
package com.implementation.jwt.model;
public class RegistrationRequest {
private String username;
private String password;
private Set<String> role;
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 Set<String>
getRole() {
return role;
}
public void setRole(Set<String>
role) {
this.role = role;
}
}
MessageResponse.java
package com.implementation.jwt.model;
public class MessageResponse {
private String message ;
public MessageResponse(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
RoleEnum.java
package com.implementation.jwt.model;
public enum RoleEnum {
ROLE_USER,
ROLE_MODERATOR,
ROLE_ADMIN
}
JwtLoginRequest.java
package com.implementation.jwt.model;
public class JwtLoginRequest {
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;
}
}
JwtResponse.java
package com.implementation.jwt.model;
import java.util.List;
public class JwtResponse {
private String token;
private String type = "Bearer";
private Long id;
private String username;
private List<String> roles;
public JwtResponse(String accessToken, Long id, String username, List<String> roles) {
this.token = accessToken;
this.id = id;
this.username = username;
this.roles = roles;
}
public String getAccessToken() {
return token;
}
public void setAccessToken(String accessToken) {
this.token = accessToken;
}
public String getTokenType() {
return type;
}
public void setTokenType(String tokenType) {
this.type = tokenType;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getRoles() {
return roles;
}
}
Note: Don’t panicking to see the compilation error. Just create the class
file as we instructed and ignore the compile error because when we will be
created all java class then the compilation dependency will resolve
automatically. We are following this straight forward process because it will
be very difficult to describe the process if we change the context from one
partially completed class to another class.
Create Repository:
Now we will create two repository classes to persist the user and role data and place into the newly created package com.implementation.jwt.service:
UserDetailsImpl.java
package com.implementation.jwt.service;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import
org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import
com.fasterxml.jackson.annotation.JsonIgnore;
import com.implementation.jwt.model.User;
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
@JsonIgnore
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserDetailsImpl(Long id, String username,String password,
Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.password = password;
this.authorities = authorities;
}
public static UserDetailsImpl build(User user) {
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getName().name()))
.collect(Collectors.toList());
return new UserDetailsImpl(
user.getId(),
user.getUsername(),
user.getPassword(),
authorities);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public Long getId() {
return id;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
UserDetailsImpl user = (UserDetailsImpl) o;
return Objects.equals(id, user.id);
}
}
UserDetailsServiceImpl.java
package com.implementation.jwt.service;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.transaction.annotation.Transactional;
import com.implementation.jwt.model.User;
import com.implementation.jwt.repository.UserRepository;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
return UserDetailsImpl.build(user);
}
}
Configure Spring Security for JWT:
Configure Spring Security for JWT create another package com.implementation.jwt.security. To expose REST POST API with mapping /api/authenticate/** using which user will get a valid JSON Web Token and then, allow the user access to the API /api/resource/** only if it has a valid token.
WebSecurityConfig.java
package com.implementation.jwt.security;
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.config.http.SessionCreationPolicy;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.implementation.jwt.service.UserDetailsServiceImpl;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtTokenAuthOncePerRequestFilter authenticationJwtTokenFilter() {
return new JwtTokenAuthOncePerRequestFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/authenticate/**").permitAll()
.antMatchers("/api/resource/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(),
UsernamePasswordAuthenticationFilter.class);
}
}
Filter the Requests:
package com.implementation.jwt.security;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import com.implementation.jwt.service.UserDetailsServiceImpl;
public class JwtTokenAuthOncePerRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
private static final Logger logger = LoggerFactory.getLogger(JwtTokenAuthOncePerRequestFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken
authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e);
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}
package com.implementation.jwt.security;
import java.io.IOException;
import javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import
org.springframework.security.core.AuthenticationException;
import
org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
logger.error("Unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
}
}
Create JWT Utility Class:
JwtUtils.java class is responsible to generate and validating the JWT token. Here we generating the JWT using HS512 algorithm and Secrete key. And we are parsing the JWT using secrete key during the validation.
package com.implementation.jwt.security;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Value;
import
org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.implementation.jwt.service.UserDetailsImpl;
import
io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import
io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${jwt.signing.key.secret}")
private String jwtSecret;
@Value("${jwt.token.expiration.in.seconds}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs * 1000))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
Create API Controller:
Create a package com.implementation.jwt.controller and JwtController.java
In this controller we have implemented two POST API for user
registration with mapping /reg
and user login with post
mapping /login.
To register, user should provide a user name, password and a
role list. If the user does not specify the roles, then it will automatically
pick the user role. Request body will user RegistrationRequest.java model
class and Response will be providing by using MessageResponse.java model.
To get the JWT token, user
have to provide valid username and password in /api/authenticate /logn post
body. Here requests model is JwtLoginRequest.java and response model is JwtResponse.java
JwtController.java
package com.implementation.jwt.controller;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.http.ResponseEntity;
import
org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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.CrossOrigin;
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
com.implementation.jwt.model.JwtLoginRequest;
import
com.implementation.jwt.model.JwtResponse;
import
com.implementation.jwt.model.MessageResponse;
import
com.implementation.jwt.model.RegistrationRequest;
import com.implementation.jwt.model.Role;
import
com.implementation.jwt.model.RoleEnum;
import com.implementation.jwt.model.User;
import com.implementation.jwt.repository.RoleRepository;
import
com.implementation.jwt.repository.UserRepository;
import
com.implementation.jwt.security.JwtUtils;
import com.implementation.jwt.service.UserDetailsImpl;
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/authenticate")
public class JwtController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserRepository userRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
PasswordEncoder encoder;
@Autowired
JwtUtils jwtUtils;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody JwtLoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(item -> item.getAuthority())
.collect(Collectors.toList());
return ResponseEntity.ok(new JwtResponse(jwt,
userDetails.getId(),
userDetails.getUsername(),
roles));
}
@PostMapping("/reg")
public ResponseEntity<?> registerUser(@RequestBody RegistrationRequest signUpRequest) {
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Username is already exist!"));
}
//
Create new user's account
User user = new User(signUpRequest.getUsername(),
encoder.encode(signUpRequest.getPassword()));
Set<String> strRoles = signUpRequest.getRole();
Set<Role> roles = new HashSet<>();
if (strRoles == null) {
Role userRole = roleRepository.findByName(RoleEnum.ROLE_USER)
.orElseThrow(()
-> new RuntimeException("Role is not found."));
roles.add(userRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository.findByName(RoleEnum.ROLE_ADMIN)
.orElseThrow(()
-> new RuntimeException("Role is not found."));
roles.add(adminRole);
break;
default:
Role userRole = roleRepository.findByName(RoleEnum.ROLE_USER)
.orElseThrow(()
-> new RuntimeException("Role is not found."));
roles.add(userRole);
}
});
}
user.setRoles(roles);
userRepository.save(user);
return ResponseEntity.ok(new MessageResponse("Registration successfully!"));
}
}
Create Resource Controller:
Now we will create another controller which will use the JWT token within the authorization header to access the resource and it will also check the user role specified during the registration. Here we create 3 GET API to show the demo:
Public Access: http://localhost:8080/api/resource/content
Grant access whose are admin or
user role and valid JWT: http://localhost:8080/api/resource/user
Grant access who has admin role
only and valid JWT: http://localhost:8080/api/resource/admin
ResourceController.java
package com.implementation.jwt.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import
org.springframework.web.bind.annotation.CrossOrigin;
import
org.springframework.web.bind.annotation.GetMapping;
import
org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/resource")
public class ResourceController
{
@GetMapping("/content")
public String publicContent() {
return "Public
Content.";
}
@GetMapping("/user")
@PreAuthorize("hasRole('USER') or
hasRole('ADMIN')")
public String userAccess() {
return "User
Content.";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
return "Admin
content";
}
}
Now check how it’s work using postman:
For user registration:
For user login and generation JWT token:
To check the role and token based accessibility call the GET API:
URL: http://localhost:8080/api/resource/content
We make it public and no need to set the authorization header for this API
URL: http://localhost:8080/api/resource/admin
Let’s try without JWT:
Let try to access the user resource with admin JWT token and It should give the access. Because we permit it in the role controller:
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public String userAccess() {
return "User Content.";
}
Let’s create a user with user role:
Generate token (JWT) using this user:
Now try to access user API with this token:
Now try to access admin resource using this user role JWT token and It should restrict the access.
No comments:
Post a Comment