fix spring cycle dependence JwtTokenManager (#8418)
* fix spring cycle dependence JwtTokenManager * remove unuse code * check code style * update test metrhod * remove unuse code * remove NacosAuthConfig logic from jwttoken * fix testUpgradeCheckSucc test
This commit is contained in:
parent
dbc1be8d8d
commit
74c3355b71
@ -241,6 +241,7 @@ public class UpgradeJudgement extends Subscriber<MembersChangeEvent> {
|
||||
if (null != upgradeChecker) {
|
||||
upgradeChecker.shutdownNow();
|
||||
}
|
||||
NotifyCenter.deregisterSubscriber(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.naming.core.v2.upgrade;
|
||||
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.core.cluster.Member;
|
||||
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
||||
@ -96,6 +97,7 @@ public class UpgradeJudgementTest {
|
||||
ApplicationUtils.injectContext(context);
|
||||
upgradeJudgement = new UpgradeJudgement(raftPeerSet, raftCore, versionJudgement, memberManager, serviceManager,
|
||||
upgradeStates, doubleWriteDelayTaskEngine);
|
||||
NotifyCenter.deregisterSubscriber(upgradeJudgement);
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -16,11 +16,14 @@
|
||||
|
||||
package com.alibaba.nacos.plugin.auth.impl;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.io.DecodingException;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@ -28,8 +31,11 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* JWT token manager.
|
||||
@ -42,8 +48,38 @@ public class JwtTokenManager {
|
||||
|
||||
private static final String AUTHORITIES_KEY = "auth";
|
||||
|
||||
@Autowired
|
||||
private NacosAuthConfig nacosAuthConfig;
|
||||
private final AuthConfigs authConfigs;
|
||||
|
||||
/**
|
||||
* secret key.
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* secret key byte array.
|
||||
*/
|
||||
private byte[] secretKeyBytes;
|
||||
|
||||
/**
|
||||
* Token validity time(seconds).
|
||||
*/
|
||||
private long tokenValidityInSeconds;
|
||||
|
||||
public JwtTokenManager(AuthConfigs authConfigs) {
|
||||
this.authConfigs = authConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* init tokenValidityInSeconds and secretKey properties.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initProperties() {
|
||||
Properties properties = authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE);
|
||||
String validitySeconds = properties
|
||||
.getProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS);
|
||||
tokenValidityInSeconds = Long.parseLong(validitySeconds);
|
||||
secretKey = properties.getProperty(AuthConstants.TOKEN_SECRET_KEY, AuthConstants.DEFAULT_TOKEN_SECRET_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create token.
|
||||
@ -67,11 +103,11 @@ public class JwtTokenManager {
|
||||
|
||||
Date validity;
|
||||
|
||||
validity = new Date(now + nacosAuthConfig.getTokenValidityInSeconds() * 1000L);
|
||||
validity = new Date(now + this.getTokenValidityInSeconds() * 1000L);
|
||||
|
||||
Claims claims = Jwts.claims().setSubject(userName);
|
||||
return Jwts.builder().setClaims(claims).setExpiration(validity)
|
||||
.signWith(Keys.hmacShaKeyFor(nacosAuthConfig.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
|
||||
.signWith(Keys.hmacShaKeyFor(this.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,7 +117,7 @@ public class JwtTokenManager {
|
||||
* @return auth info
|
||||
*/
|
||||
public Authentication getAuthentication(String token) {
|
||||
Claims claims = Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build()
|
||||
Claims claims = Jwts.parserBuilder().setSigningKey(this.getSecretKeyBytes()).build()
|
||||
.parseClaimsJws(token).getBody();
|
||||
|
||||
List<GrantedAuthority> authorities = AuthorityUtils
|
||||
@ -97,7 +133,22 @@ public class JwtTokenManager {
|
||||
* @param token token
|
||||
*/
|
||||
public void validateToken(String token) {
|
||||
Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build().parseClaimsJws(token);
|
||||
Jwts.parserBuilder().setSigningKey(this.getSecretKeyBytes()).build().parseClaimsJws(token);
|
||||
}
|
||||
|
||||
public byte[] getSecretKeyBytes() {
|
||||
if (secretKeyBytes == null) {
|
||||
try {
|
||||
secretKeyBytes = Decoders.BASE64.decode(secretKey);
|
||||
} catch (DecodingException e) {
|
||||
secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
return secretKeyBytes;
|
||||
}
|
||||
|
||||
public long getTokenValidityInSeconds() {
|
||||
return tokenValidityInSeconds;
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,9 @@ package com.alibaba.nacos.plugin.auth.impl;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes;
|
||||
import com.alibaba.nacos.plugin.auth.impl.filter.JwtAuthenticationTokenFilter;
|
||||
import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.io.DecodingException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -42,8 +39,6 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||
import org.springframework.web.cors.CorsUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Spring security config.
|
||||
@ -75,21 +70,6 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final ControllerMethodsCache methodsCache;
|
||||
|
||||
/**
|
||||
* secret key.
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* secret key byte array.
|
||||
*/
|
||||
private byte[] secretKeyBytes;
|
||||
|
||||
/**
|
||||
* Token validity time(seconds).
|
||||
*/
|
||||
private long tokenValidityInSeconds;
|
||||
|
||||
public NacosAuthConfig(Environment env, JwtTokenManager tokenProvider, AuthConfigs authConfigs,
|
||||
NacosUserDetailsServiceImpl userDetailsService,
|
||||
ObjectProvider<LdapAuthenticationProvider> ldapAuthenticationProvider,
|
||||
@ -110,15 +90,6 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
methodsCache.initClassMethod("com.alibaba.nacos.plugin.auth.impl.controller");
|
||||
initProperties();
|
||||
}
|
||||
|
||||
private void initProperties() {
|
||||
Properties properties = authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE);
|
||||
String validitySeconds = properties
|
||||
.getProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS);
|
||||
tokenValidityInSeconds = Long.parseLong(validitySeconds);
|
||||
secretKey = properties.getProperty(AuthConstants.TOKEN_SECRET_KEY, AuthConstants.DEFAULT_TOKEN_SECRET_KEY);
|
||||
}
|
||||
|
||||
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
|
||||
@ -177,20 +148,4 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
public byte[] getSecretKeyBytes() {
|
||||
if (secretKeyBytes == null) {
|
||||
try {
|
||||
secretKeyBytes = Decoders.BASE64.decode(secretKey);
|
||||
} catch (DecodingException e) {
|
||||
secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
return secretKeyBytes;
|
||||
}
|
||||
|
||||
public long getTokenValidityInSeconds() {
|
||||
return tokenValidityInSeconds;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
|
||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.plugin.auth.impl.JwtTokenManager;
|
||||
import com.alibaba.nacos.plugin.auth.impl.NacosAuthConfig;
|
||||
import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes;
|
||||
@ -83,9 +82,6 @@ public class UserController {
|
||||
@Autowired
|
||||
private AuthConfigs authConfigs;
|
||||
|
||||
@Autowired
|
||||
private NacosAuthConfig nacosAuthConfig;
|
||||
|
||||
@Autowired
|
||||
private NacosAuthManager authManager;
|
||||
|
||||
@ -218,7 +214,7 @@ public class UserController {
|
||||
|
||||
ObjectNode result = JacksonUtils.createEmptyJsonNode();
|
||||
result.put(Constants.ACCESS_TOKEN, user.getToken());
|
||||
result.put(Constants.TOKEN_TTL, nacosAuthConfig.getTokenValidityInSeconds());
|
||||
result.put(Constants.TOKEN_TTL, jwtTokenManager.getTokenValidityInSeconds());
|
||||
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
|
||||
result.put(Constants.USERNAME, user.getUserName());
|
||||
return result;
|
||||
|
@ -17,16 +17,12 @@
|
||||
package com.alibaba.nacos.plugin.auth.impl;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
@ -37,18 +33,9 @@ public class JwtTokenManagerTest {
|
||||
@Mock
|
||||
private AuthConfigs authConfigs;
|
||||
|
||||
@Mock
|
||||
private ControllerMethodsCache methodsCache;
|
||||
|
||||
@Mock
|
||||
private ObjectProvider<LdapAuthenticationProvider> ldapAuthenticationProvider;
|
||||
|
||||
private NacosAuthConfig nacosAuthConfig;
|
||||
|
||||
@Test
|
||||
public void testCreateTokenAndSecretKeyWithoutSpecialSymbol() throws NoSuchFieldException, IllegalAccessException {
|
||||
createToken("SecretKey0123$567890$234567890123456789012345678901234567890123456789");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -61,23 +48,10 @@ public class JwtTokenManagerTest {
|
||||
properties.setProperty(AuthConstants.TOKEN_SECRET_KEY, secretKey);
|
||||
properties.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, "300");
|
||||
when(authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE)).thenReturn(properties);
|
||||
|
||||
nacosAuthConfig = new NacosAuthConfig(null, null, authConfigs, null,
|
||||
ldapAuthenticationProvider, methodsCache);
|
||||
nacosAuthConfig.init();
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager();
|
||||
injectProperty(jwtTokenManager, "nacosAuthConfig", nacosAuthConfig);
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager(authConfigs);
|
||||
jwtTokenManager.initProperties();
|
||||
String nacosToken = jwtTokenManager.createToken("nacos");
|
||||
Assert.notNull(nacosToken);
|
||||
jwtTokenManager.validateToken(nacosToken);
|
||||
}
|
||||
|
||||
private void injectProperty(Object o, String propertyName, Object value)
|
||||
throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> aClass = o.getClass();
|
||||
Field declaredField = aClass.getDeclaredField(propertyName);
|
||||
declaredField.setAccessible(true);
|
||||
declaredField.set(o, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ package com.alibaba.nacos.plugin.auth.impl.controller;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.plugin.auth.impl.NacosAuthConfig;
|
||||
import com.alibaba.nacos.plugin.auth.impl.JwtTokenManager;
|
||||
import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes;
|
||||
import com.alibaba.nacos.plugin.auth.impl.users.NacosUser;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -32,6 +33,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@ -41,6 +43,9 @@ import static org.mockito.Mockito.when;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UserControllerTest {
|
||||
|
||||
@Mock(lenient = true)
|
||||
JwtTokenManager jwtTokenManager;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@ -50,9 +55,6 @@ public class UserControllerTest {
|
||||
@Mock
|
||||
private AuthConfigs authConfigs;
|
||||
|
||||
@Mock
|
||||
private NacosAuthConfig nacosAuthConfig;
|
||||
|
||||
@Mock
|
||||
private NacosAuthManager authManager;
|
||||
|
||||
@ -69,19 +71,25 @@ public class UserControllerTest {
|
||||
user.setToken("1234567890");
|
||||
injectObject("authConfigs", authConfigs);
|
||||
injectObject("authManager", authManager);
|
||||
injectObject("nacosAuthConfig", nacosAuthConfig);
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(AuthConstants.TOKEN_SECRET_KEY, "SecretKey012345678901234567890123456789012345678901234567890123456789");
|
||||
properties.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, "300");
|
||||
when(authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE)).thenReturn(properties);
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager(authConfigs);
|
||||
jwtTokenManager.initProperties();
|
||||
injectObject("jwtTokenManager", jwtTokenManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoginWithAuthedUser() throws AccessException {
|
||||
when(authManager.login(request)).thenReturn(user);
|
||||
when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name());
|
||||
when(nacosAuthConfig.getTokenValidityInSeconds()).thenReturn(18000L);
|
||||
when(jwtTokenManager.getTokenValidityInSeconds()).thenReturn(18000L);
|
||||
Object actual = userController.login("nacos", "nacos", response, request);
|
||||
assertThat(actual, instanceOf(JsonNode.class));
|
||||
String actualString = actual.toString();
|
||||
assertTrue(actualString.contains("\"accessToken\":\"1234567890\""));
|
||||
assertTrue(actualString.contains("\"tokenTtl\":18000"));
|
||||
assertTrue(actualString.contains("\"tokenTtl\":300"));
|
||||
assertTrue(actualString.contains("\"globalAdmin\":true"));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user