club.zhcs.lina.oidc.service.CacheableOpenidConnectionAuthService Maven / Gradle / Ivy
The newest version!
package club.zhcs.lina.oidc.service;
import java.util.concurrent.TimeUnit;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.springframework.http.HttpHeaders;
import club.zhcs.lina.auth.AuthorizationException;
import club.zhcs.lina.auth.service.AuthService;
import club.zhcs.lina.auth.service.AuthUser;
import club.zhcs.lina.auth.service.UserDetailService;
import club.zhcs.lina.oidc.service.TokenRefreshableRiemannAuthService.CookieSettings;
import club.zhcs.lina.oidc.service.jwt.JwtDecoder;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
/**
* 基于open id connect 实现的token验证可缓存的实现
*/
@RequiredArgsConstructor
public class CacheableOpenidConnectionAuthService implements AuthService {
private final JwtDecoder jwtDecoder;
private final CookieSettings cookieSettings;
private final HttpServletRequest request;
private final HttpServletResponse response;
private final UserDetailService userDetailService;
private static final String TOKEN_EXPIRED = "Token已过期!";
@Override
public void login(AuthUser user) {
userDetailService.save(user);
addCookie(cookieSettings.getTokenCookieName(), user.getToken(), cookieSettings.getTokenMinutes());
addCookie(cookieSettings.getRefreshTokenCookieName(), user.getRefreshToken(), cookieSettings.getRefreshTokenMinutes());
}
/**
* 根据用户名获取用户
*
* @param userName
* @return
*/
private AuthUser subject2User(String userName) {
return userDetailService.userByName(userName);
}
@Override
public AuthUser user() {
String token = token();
String refreshToken = refreshToken();
if (Strings.isBlank(token) && Strings.isBlank(refreshToken)) {
throw Lang.makeThrow(AuthorizationException.class, "用户未登录!");
}
String userName = jwtDecoder.subject(token);
if (Strings.isBlank(userName)) {
return tryRefreshToken(refreshToken);
}
return subject2User(userName);
}
/**
* 尝试刷新token
*
* @param refreshToken
* @return
*/
private AuthUser tryRefreshToken(String refreshToken) {
String userName = jwtDecoder.subject(refreshToken);
if (Strings.isBlank(userName)) {
throw Lang.makeThrow(AuthorizationException.class, TOKEN_EXPIRED);// refreshToken也过期了
}
AuthUser user = subject2User(userName);
// 刷新token通过cookie带回去
addCookie(cookieSettings.getTokenCookieName(), user.getToken(), cookieSettings.getTokenMinutes());
addCookie(cookieSettings.getRefreshTokenCookieName(), user.getRefreshToken(), cookieSettings.getRefreshTokenMinutes());
return user;
}
@Override
public HttpServletRequest getRequest() {
return request;
}
@Override
public String authorizationHeaderKey() {
return HttpHeaders.AUTHORIZATION;
}
@Override
public String tokenKey() {
return cookieSettings.getTokenCookieName();
}
@Override
public String refreshTokenKey() {
return cookieSettings.getRefreshTokenCookieName();
}
@Override
public void logout() {
addCookie(cookieSettings.getTokenCookieName(), null, 0);
addCookie(cookieSettings.getRefreshTokenCookieName(), null, 0);
}
private void addCookie(String name, String value, int age) {
Cookie cookie = new Cookie(name, value);
if (Strings.isNotBlank(cookieSettings.getPath())) {
cookie.setPath(cookieSettings.getPath());
}
if (Strings.isNotBlank(cookieSettings.getDomain())) {
cookie.setDomain(cookieSettings.getDomain());
}
if (cookieSettings.isSecure()) {
cookie.setSecure(true);
}
if (cookieSettings.isHttpOnly()) {
cookie.setHttpOnly(true);
}
cookie.setMaxAge((int) TimeUnit.MINUTES.toMillis(age));
response.addCookie(cookie);
}
}