package com.moral.security.endpoint; import com.moral.entity.Account; import com.moral.security.auth.JwtAuthenticationToken; import com.moral.security.auth.login.LoginMode; import com.moral.security.model.token.JwtTokenFactory; import com.moral.security.auth.jwt.extractor.TokenExtractor; import com.moral.security.auth.jwt.verifier.TokenVerifier; import com.moral.security.config.JwtSettings; import com.moral.security.config.WebSecurityConfig; import com.moral.security.exceptions.InvalidJwtToken; import com.moral.security.model.UserContext; import com.moral.security.model.token.JwtToken; import com.moral.security.model.token.RawAccessJwtToken; import com.moral.security.model.token.RefreshToken; import com.moral.service.AccountService; 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 javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.stream.Collectors; /** * RefreshTokenEndpoint * * @author vladimir.stankovic * * Aug 17, 2016 */ @RestController public class RefreshTokenEndpoint { @Autowired private JwtTokenFactory tokenFactory; @Autowired private JwtSettings jwtSettings; @Autowired private AccountService accountService; @Autowired private TokenVerifier tokenVerifier; @Autowired @Qualifier("jwtHeaderTokenExtractor") private TokenExtractor tokenExtractor; @RequestMapping(value="/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.AUTHENTICATION_HEADER_NAME)); 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(); // 从refresh token里 拿到登录方式 LoginMode mode = LoginMode.valueOf(refreshToken.getClaims().getBody().get("mode").toString()); Account account = accountService.queryAccountByName(subject).orElseThrow(() -> new UsernameNotFoundException("User not found: " + subject)); if (account.getRoles() == null) throw new InsufficientAuthenticationException("User has no roles assigned"); List authorities = account.getRoles().stream() .map(authority -> new SimpleGrantedAuthority(authority.getName())) .collect(Collectors.toList()); UserContext userContext = UserContext.create(account.getAccountName(),mode,account.getOrganizationId(),authorities); return tokenFactory.createAccessJwtToken(userContext); } }