import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Verification;
import com.cmiinv.shp.auth.config.AuthConfig;
import com.cmiinv.shp.util.api.ApiResponse;
import com.cmiinv.shp.util.api.ErrorCodes;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Setter;
import org.apache.shiro.authc.AuthenticationException;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.core.env.Environment;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;
public abstract class AuthService implements MessageSourceAware, EnvironmentAware {
@Autowired
protected AuthConfig authConfig;
@Autowired
private ObjectMapper objectMapper;
@Setter
private MessageSource messageSource;
@Setter
private Environment environment;
@Autowired
private RequestCrossOriginLocator requestCrossOriginLocator;
public String buildJWTToken(JWTPrincipal principal) {
try {
Algorithm algorithm = Algorithm.HMAC256(principal.getSecret());
JWTCreator.Builder builder = JWT.create();
builder.withSubject(principal.getSubject());
Date expiresAt = DateTime.now().plusDays(authConfig.getJwtExpirationDays()).toDate();
builder.withExpiresAt(expiresAt);
if (!principal.getRoles().isEmpty()) {
builder.withArrayClaim("roles", principal.getRoles().toArray(new String[0]));
}
withClaims(builder, principal);
return builder.sign(algorithm);
} catch (UnsupportedEncodingException e) {
throw new AuthenticationException(e);
}
}
void verifyJWTToken(JWTToken token, JWTPrincipal principal) {
try {
Algorithm algorithm = Algorithm.HMAC256(principal.getSecret());
Verification verification = JWT.require(algorithm);
verification.withSubject(principal.getSubject());
if (!principal.getRoles().isEmpty()) {
verification.withArrayClaim("roles", principal.getRoles().toArray(new String[0]));
}
withClaims(verification, principal);
verification.build().verify(token.getToken());
} catch (UnsupportedEncodingException | JWTVerificationException e) {
throw new AuthenticationException("invalid user credential info", e);
}
}
protected void withClaims(JWTCreator.Builder builder, JWTPrincipal principal) {
// may be overridden to provide extra jwt claims when building the token
}
protected void withClaims(Verification verification, JWTPrincipal principal) {
// may be overridden to provide extra jwt claims when verifying the token
}
String buildChallengeResponse() throws IOException {
String code = ErrorCodes.SESSION_EXPIRATION;
String message = messageSource.getMessage(code, null, Locale.getDefault());
ApiResponse<Void> response = ApiResponse.failure(code, message, null);
return objectMapper.writeValueAsString(response);
}
String getValidRequestCrossOrigin(HttpServletRequest request) {
return requestCrossOriginLocator.locateOrigin(request);
}
boolean isDeveloping() {
return environment.acceptsProfiles("development");
}
public abstract Optional<JWTPrincipal> getAuthPrincipal(JWTToken token);
}
UserAuthService.java继承抽象类子类参考代码
package com.qbsea.mysboot2mybatis.mysboot2shirojwt.api.v1.service;
import com.qbsea.mysboot2mybatis.mysboot2shirojwt.AuthService;
import com.qbsea.mysboot2mybatis.mysboot2shirojwt.JWTPrincipal;
import com.qbsea.mysboot2mybatis.mysboot2shirojwt.JWTToken;
import com.qbsea.mysboot2mybatis.mysboot2shirojwt.api.v1.model.TUser;
import com.qbsea.mysboot2mybatis.mysboot2shirojwt.api.v1.model.UserPrincipal;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserAuthService extends AuthService {
@Override
public Optional<JWTPrincipal> getAuthPrincipal(JWTToken token) {
String subject = token.getDecodedToken().getSubject();
long userId = Long.parseLong(subject);
TUser tUser = new TUser();//通过userId 从数据库里查询
tUser.setId(1l);
tUser.setLocked(false);
tUser.setMobile("15011083984");
tUser.setPassword("123456");
if(tUser==null){
return Optional.empty();
}
UserPrincipal userPrincipal = new UserPrincipal();
userPrincipal.setId(tUser.getId());
userPrincipal.setLocked(tUser.getLocked());
userPrincipal.setMobile(tUser.getMobile());
userPrincipal.setPassword(tUser.getPassword());
return Optional.of(userPrincipal);
}
}