springboot-security-jwt/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java
2016-08-19 16:58:25 +02:00

77 lines
3.4 KiB
Java

package com.svlada.security.endpoint;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.svlada.entity.User;
import com.svlada.security.UserService;
import com.svlada.security.auth.jwt.extractor.TokenExtractor;
import com.svlada.security.auth.jwt.verifier.TokenVerifier;
import com.svlada.security.config.JwtSettings;
import com.svlada.security.config.WebSecurityConfig;
import com.svlada.security.exceptions.InvalidJwtToken;
import com.svlada.security.model.UserContext;
import com.svlada.security.model.token.JwtToken;
import com.svlada.security.model.token.JwtTokenFactory;
import com.svlada.security.model.token.RawAccessJwtToken;
import com.svlada.security.model.token.RefreshToken;
/**
* RefreshTokenEndpoint
*
* @author vladimir.stankovic
*
* Aug 17, 2016
*/
@RestController
public class RefreshTokenEndpoint {
@Autowired private JwtTokenFactory tokenFactory;
@Autowired private JwtSettings jwtSettings;
@Autowired private UserService userService;
@Autowired private TokenVerifier tokenVerifier;
@Autowired @Qualifier("jwtHeaderTokenExtractor") private TokenExtractor tokenExtractor;
@RequestMapping(value="/api/auth/token", method=RequestMethod.GET, produces={ MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody JwtToken refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String tokenPayload = tokenExtractor.extract(request.getHeader(WebSecurityConfig.JWT_TOKEN_HEADER_PARAM));
RawAccessJwtToken rawToken = new RawAccessJwtToken(tokenPayload);
RefreshToken refreshToken = RefreshToken.create(rawToken, jwtSettings.getTokenSigningKey()).orElseThrow(() -> new InvalidJwtToken());
String jti = refreshToken.getJti();
if (!tokenVerifier.verify(jti)) {
throw new InvalidJwtToken();
}
String subject = refreshToken.getSubject();
User user = userService.getByUsername(subject).orElseThrow(() -> new UsernameNotFoundException("User not found: " + subject));
if (user.getRoles() == null) throw new InsufficientAuthenticationException("User has no roles assigned");
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getRole().authority()))
.collect(Collectors.toList());
UserContext userContext = UserContext.create(user.getUsername(), authorities);
return tokenFactory.createAccessJwtToken(userContext);
}
}