I am doing spring security for REST API using JWT. I have already done with creating web token with expiry time and its working fine . I have set the time limit to 5 minutes . After 5 minutes, the token will get expired. This causes problem for me, so can anyone guide me how to solve this one by using refresh token, since I am very new to this concept.
Here is my code..
SpringSecurityConfiguration
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilter() {
JwtAuthenticationTokenFilter filter = new
JwtAuthenticationTokenFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/admin/**").authenticated()
.antMatchers("/admin/**").hasAnyAuthority("Admin")
.and()
.exceptionHandling().authenticationEntryPoint(entryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
TokenController
@RestController
@RequestMapping("/token")
public class TokenController {
private JwtGenerator jwtGenerator;
public TokenController(JwtGenerator jwtGenerator) {
this.jwtGenerator = jwtGenerator;
}
@RequestMapping(method = RequestMethod.POST)
public String generate(@RequestBody final User user) {
return jwtGenerator.generate(user);
}
}
JwtGenerator
@Component
public class JwtGenerator {
private Long expiration;
private String secret = "youtube";
static final String CLAIM_KEY_CREATED = "created";
public String generate(User user) {
Claims claims = Jwts.claims()
.setSubject(user.getFirstName());
claims.put("password", String.valueOf(user.getPassword()));
//claims.put("role", jwtUser.getRole());
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, "youtube")
.compact();
}
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + (5 * 60 * 1000));
}
}
JwtAuthenticationProvider
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) usernamePasswordAuthenticationToken;
String token = jwtAuthenticationToken.getToken();
User user = validator.validate(token);
if (user == null) {
throw new RuntimeException("JWT Token is incorrect");
}
String firstname=user.getFirstName();
User user1=userRepository.getRoleId(firstname);
List<GrantedAuthority> grantedAuthorities = AuthorityUtils
.commaSeparatedStringToAuthorityList(user1.getRole().getRoleName());
return new JwtUserDetails(user.getFirstName(), user.getPassword(),
token,
grantedAuthorities);
}
@Override
public boolean supports(Class<?> aClass) {
return (JwtAuthenticationToken.class.isAssignableFrom(aClass));
}
JwtValidator
@Component
public class JwtValidator {
private String secret = "youtube";
public User validate(String token) {
User user = null;
try {
Claims body = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
user = new User();
user.setFirstName(body.getSubject());
user.setPassword((String) body.get("password"));
//user.setRole((String) body.get("role"));
}
catch (Exception e) {
System.out.println(e);
}
return user;
}
}
I am passing username and password to get the token.Thanks in advance
In the URL field enter the address to the refresh token route of your local API - http://localhost:4000/users/refresh-token . Click the Send button, you should receive a "200 OK" response containing the user details and a JWT token, and a cookie containing a new refresh token.
To refresh the token, your API needs a new endpoint that receives a valid, not expired JWT and returns the same signed JWT with the new expiration field. Then the web application will store the token somewhere.
This allows you to have short-lived access tokens without having to collect credentials every time one expires. Since access tokens aren't valid for an extended period because of security reasons, a refresh token helps to re-authenticate a user without login credentials.
You will probably need to change a little bit existing solution. You have to in general after successfull authorization return 2 JWT tokens - one 'access' JWT token used to any other authorized request to server, and the 'refresh' JWT token which is used to retrieve new 'access' JWT token when first one expired. It also means that You will need to change/modify/intercept front-end part of application to apply these rules. Good point is for me here JWT Authentication Tutorial - An example using Spring Boot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With