Move plugin config to nacos-auth-plugin-impl module.
This commit is contained in:
parent
aba0facf90
commit
9020bb9d6e
15
auth/pom.xml
15
auth/pom.xml
@ -59,21 +59,6 @@
|
|||||||
<groupId>org.apache.tomcat.embed</groupId>
|
<groupId>org.apache.tomcat.embed</groupId>
|
||||||
<artifactId>tomcat-embed-core</artifactId>
|
<artifactId>tomcat-embed-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-impl</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-jackson</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -16,23 +16,24 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.auth.config;
|
package com.alibaba.nacos.auth.config;
|
||||||
|
|
||||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
|
||||||
import com.alibaba.nacos.common.JustForTest;
|
import com.alibaba.nacos.common.JustForTest;
|
||||||
import com.alibaba.nacos.common.event.ServerConfigChangeEvent;
|
import com.alibaba.nacos.common.event.ServerConfigChangeEvent;
|
||||||
import com.alibaba.nacos.common.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||||
|
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
import com.alibaba.nacos.sys.utils.PropertiesUtil;
|
||||||
import io.jsonwebtoken.io.DecodingException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth related configurations.
|
* Auth related configurations.
|
||||||
@ -46,6 +47,8 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AuthConfigs.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(AuthConfigs.class);
|
||||||
|
|
||||||
|
private static final String PREFIX = "nacos.core.auth.plugin";
|
||||||
|
|
||||||
@JustForTest
|
@JustForTest
|
||||||
private static Boolean cachingEnabled = null;
|
private static Boolean cachingEnabled = null;
|
||||||
|
|
||||||
@ -55,23 +58,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
|
|||||||
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLED + ":false}")
|
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLED + ":false}")
|
||||||
private boolean authEnabled;
|
private boolean authEnabled;
|
||||||
|
|
||||||
/**
|
|
||||||
* secret key.
|
|
||||||
*/
|
|
||||||
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_DEFAULT_TOKEN_SECRET_KEY + ":}")
|
|
||||||
private String secretKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* secret key byte array.
|
|
||||||
*/
|
|
||||||
private byte[] secretKeyBytes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Token validity time(seconds).
|
|
||||||
*/
|
|
||||||
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_DEFAULT_TOKEN_EXPIRE_SECONDS + ":18000}")
|
|
||||||
private long tokenValidityInSeconds;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which auth system is in use.
|
* Which auth system is in use.
|
||||||
*/
|
*/
|
||||||
@ -87,24 +73,30 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
|
|||||||
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE + ":false}")
|
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE + ":false}")
|
||||||
private boolean enableUserAgentAuthWhite;
|
private boolean enableUserAgentAuthWhite;
|
||||||
|
|
||||||
|
private Map<String, Properties> authPluginProperties = new HashMap<>();
|
||||||
|
|
||||||
public AuthConfigs() {
|
public AuthConfigs() {
|
||||||
NotifyCenter.registerSubscriber(this);
|
NotifyCenter.registerSubscriber(this);
|
||||||
|
refreshPluginProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getSecretKeyBytes() {
|
private void refreshPluginProperties() {
|
||||||
if (secretKeyBytes == null) {
|
try {
|
||||||
try {
|
Map<String, Properties> newProperties = new HashMap<>();
|
||||||
secretKeyBytes = Decoders.BASE64.decode(secretKey);
|
Properties properties = PropertiesUtil.getPropertiesWithPrefix(EnvUtil.getEnvironment(), PREFIX);
|
||||||
} catch (DecodingException e) {
|
for (String each : properties.stringPropertyNames()) {
|
||||||
secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
|
int typeIndex = each.indexOf('.');
|
||||||
|
String type = each.substring(0, typeIndex);
|
||||||
|
if (!newProperties.containsKey(type)) {
|
||||||
|
newProperties.put(type, new Properties());
|
||||||
|
}
|
||||||
|
String subKey = each.substring(typeIndex + 1);
|
||||||
|
newProperties.get(type).setProperty(subKey, properties.getProperty(each));
|
||||||
}
|
}
|
||||||
|
authPluginProperties = newProperties;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.warn("Refresh plugin properties failed ", e);
|
||||||
}
|
}
|
||||||
return secretKeyBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTokenValidityInSeconds() {
|
|
||||||
return tokenValidityInSeconds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNacosAuthSystemType() {
|
public String getNacosAuthSystemType() {
|
||||||
@ -141,8 +133,15 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
|
|||||||
if (Objects.nonNull(AuthConfigs.cachingEnabled)) {
|
if (Objects.nonNull(AuthConfigs.cachingEnabled)) {
|
||||||
return cachingEnabled;
|
return cachingEnabled;
|
||||||
}
|
}
|
||||||
return ConvertUtils.toBoolean(
|
return ConvertUtils.toBoolean(EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, "true"));
|
||||||
EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, "true"));
|
}
|
||||||
|
|
||||||
|
public Properties getAuthPluginProperties(String authType) {
|
||||||
|
if (!authPluginProperties.containsKey(authType)) {
|
||||||
|
LOGGER.warn("Can't find properties for type {}, will use empty properties", authType);
|
||||||
|
return new Properties();
|
||||||
|
}
|
||||||
|
return authPluginProperties.get(authType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JustForTest
|
@JustForTest
|
||||||
@ -154,14 +153,13 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
|
|||||||
public void onEvent(ServerConfigChangeEvent event) {
|
public void onEvent(ServerConfigChangeEvent event) {
|
||||||
try {
|
try {
|
||||||
authEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_ENABLED, Boolean.class, false);
|
authEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_ENABLED, Boolean.class, false);
|
||||||
cachingEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, Boolean.class,
|
cachingEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, Boolean.class, true);
|
||||||
true);
|
|
||||||
serverIdentityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_KEY, "");
|
serverIdentityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_KEY, "");
|
||||||
serverIdentityValue = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE, "");
|
serverIdentityValue = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE, "");
|
||||||
enableUserAgentAuthWhite = EnvUtil.getProperty(
|
enableUserAgentAuthWhite = EnvUtil
|
||||||
Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class,
|
.getProperty(Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class, false);
|
||||||
false);
|
|
||||||
nacosAuthSystemType = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SYSTEM_TYPE, "");
|
nacosAuthSystemType = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SYSTEM_TYPE, "");
|
||||||
|
refreshPluginProperties();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.warn("Upgrade auth config from env failed, use old value", e);
|
LOGGER.warn("Upgrade auth config from env failed, use old value", e);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ public class AuthConfigsTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
environment = new MockEnvironment();
|
environment = new MockEnvironment();
|
||||||
EnvUtil.setEnvironment(environment);
|
EnvUtil.setEnvironment(environment);
|
||||||
|
environment.setProperty("nacos.core.auth.plugin.test.key", "test");
|
||||||
authConfigs = new AuthConfigs();
|
authConfigs = new AuthConfigs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,16 +120,6 @@ nacos.core.auth.system.type=nacos
|
|||||||
### If turn on auth system:
|
### If turn on auth system:
|
||||||
nacos.core.auth.enabled=false
|
nacos.core.auth.enabled=false
|
||||||
|
|
||||||
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
|
||||||
# nacos.core.auth.ldap.url=ldap://localhost:389
|
|
||||||
# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com
|
|
||||||
|
|
||||||
### The token expiration in seconds:
|
|
||||||
nacos.core.auth.default.token.expire.seconds=18000
|
|
||||||
|
|
||||||
### The default token:
|
|
||||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
|
||||||
|
|
||||||
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
|
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
|
||||||
nacos.core.auth.caching.enabled=true
|
nacos.core.auth.caching.enabled=true
|
||||||
|
|
||||||
@ -141,8 +131,15 @@ nacos.core.auth.enable.userAgentAuthWhite=false
|
|||||||
nacos.core.auth.server.identity.key=serverIdentity
|
nacos.core.auth.server.identity.key=serverIdentity
|
||||||
nacos.core.auth.server.identity.value=security
|
nacos.core.auth.server.identity.value=security
|
||||||
|
|
||||||
### authority key in request:
|
### worked when nacos.core.auth.system.type=nacos
|
||||||
nacos.core.auth.authorityKey=authority,username,password
|
### The token expiration in seconds:
|
||||||
|
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
|
||||||
|
### The default token:
|
||||||
|
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||||
|
|
||||||
|
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
||||||
|
# nacos.core.auth.ldap.url=ldap://localhost:389
|
||||||
|
# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com
|
||||||
|
|
||||||
#*************** Istio Related Configurations ***************#
|
#*************** Istio Related Configurations ***************#
|
||||||
### If turn on the MCP server:
|
### If turn on the MCP server:
|
||||||
|
@ -146,16 +146,6 @@ nacos.core.auth.system.type=nacos
|
|||||||
### If turn on auth system:
|
### If turn on auth system:
|
||||||
nacos.core.auth.enabled=false
|
nacos.core.auth.enabled=false
|
||||||
|
|
||||||
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
|
||||||
# nacos.core.auth.ldap.url=ldap://localhost:389
|
|
||||||
# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com
|
|
||||||
|
|
||||||
### The token expiration in seconds:
|
|
||||||
nacos.core.auth.default.token.expire.seconds=18000
|
|
||||||
|
|
||||||
### The default token:
|
|
||||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
|
||||||
|
|
||||||
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
|
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
|
||||||
nacos.core.auth.caching.enabled=true
|
nacos.core.auth.caching.enabled=true
|
||||||
|
|
||||||
@ -167,6 +157,16 @@ nacos.core.auth.enable.userAgentAuthWhite=false
|
|||||||
nacos.core.auth.server.identity.key=serverIdentity
|
nacos.core.auth.server.identity.key=serverIdentity
|
||||||
nacos.core.auth.server.identity.value=security
|
nacos.core.auth.server.identity.value=security
|
||||||
|
|
||||||
|
### worked when nacos.core.auth.system.type=nacos
|
||||||
|
### The token expiration in seconds:
|
||||||
|
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
|
||||||
|
### The default token:
|
||||||
|
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||||
|
|
||||||
|
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
||||||
|
# nacos.core.auth.ldap.url=ldap://localhost:389
|
||||||
|
# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com
|
||||||
|
|
||||||
#*************** Istio Related Configurations ***************#
|
#*************** Istio Related Configurations ***************#
|
||||||
### If turn on the MCP server:
|
### If turn on the MCP server:
|
||||||
nacos.istio.mcp.server.enabled=false
|
nacos.istio.mcp.server.enabled=false
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.plugin.auth.impl;
|
package com.alibaba.nacos.plugin.auth.impl;
|
||||||
|
|
||||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
@ -44,7 +43,7 @@ public class JwtTokenManager {
|
|||||||
private static final String AUTHORITIES_KEY = "auth";
|
private static final String AUTHORITIES_KEY = "auth";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AuthConfigs authConfigs;
|
private NacosAuthConfig nacosAuthConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create token.
|
* Create token.
|
||||||
@ -67,11 +66,12 @@ public class JwtTokenManager {
|
|||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
Date validity;
|
Date validity;
|
||||||
validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L);
|
|
||||||
|
validity = new Date(now + nacosAuthConfig.getTokenValidityInSeconds() * 1000L);
|
||||||
|
|
||||||
Claims claims = Jwts.claims().setSubject(userName);
|
Claims claims = Jwts.claims().setSubject(userName);
|
||||||
return Jwts.builder().setClaims(claims).setExpiration(validity)
|
return Jwts.builder().setClaims(claims).setExpiration(validity)
|
||||||
.signWith(Keys.hmacShaKeyFor(authConfigs.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
|
.signWith(Keys.hmacShaKeyFor(nacosAuthConfig.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +81,7 @@ public class JwtTokenManager {
|
|||||||
* @return auth info
|
* @return auth info
|
||||||
*/
|
*/
|
||||||
public Authentication getAuthentication(String token) {
|
public Authentication getAuthentication(String token) {
|
||||||
Claims claims = Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build()
|
Claims claims = Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build()
|
||||||
.parseClaimsJws(token).getBody();
|
.parseClaimsJws(token).getBody();
|
||||||
|
|
||||||
List<GrantedAuthority> authorities = AuthorityUtils
|
List<GrantedAuthority> authorities = AuthorityUtils
|
||||||
@ -97,7 +97,7 @@ public class JwtTokenManager {
|
|||||||
* @param token token
|
* @param token token
|
||||||
*/
|
*/
|
||||||
public void validateToken(String token) {
|
public void validateToken(String token) {
|
||||||
Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build().parseClaimsJws(token);
|
Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build().parseClaimsJws(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,12 @@ package com.alibaba.nacos.plugin.auth.impl;
|
|||||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
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.constant.AuthSystemTypes;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.filter.JwtAuthenticationTokenFilter;
|
import com.alibaba.nacos.plugin.auth.impl.filter.JwtAuthenticationTokenFilter;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl;
|
import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl;
|
||||||
|
import io.jsonwebtoken.io.Decoders;
|
||||||
|
import io.jsonwebtoken.io.DecodingException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
@ -39,6 +42,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
|||||||
import org.springframework.web.cors.CorsUtils;
|
import org.springframework.web.cors.CorsUtils;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security config.
|
* Spring security config.
|
||||||
@ -76,12 +81,36 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ControllerMethodsCache methodsCache;
|
private ControllerMethodsCache methodsCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* secret key.
|
||||||
|
*/
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* secret key byte array.
|
||||||
|
*/
|
||||||
|
private byte[] secretKeyBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token validity time(seconds).
|
||||||
|
*/
|
||||||
|
private long tokenValidityInSeconds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init.
|
* Init.
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
methodsCache.initClassMethod("com.alibaba.nacos.plugin.auth.impl.controller");
|
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)
|
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
|
||||||
@ -141,4 +170,19 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
|
|||||||
return new BCryptPasswordEncoder();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,6 @@ import java.util.List;
|
|||||||
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
|
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
|
||||||
public class NacosAuthPluginService implements AuthPluginService {
|
public class NacosAuthPluginService implements AuthPluginService {
|
||||||
|
|
||||||
private static final String AUTH_PLUGIN_TYPE = "nacos";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_PARAM_KEY = "user";
|
private static final String USER_IDENTITY_PARAM_KEY = "user";
|
||||||
|
|
||||||
private static final List<String> IDENTITY_NAMES = new LinkedList<String>() {
|
private static final List<String> IDENTITY_NAMES = new LinkedList<String>() {
|
||||||
@ -77,7 +75,7 @@ public class NacosAuthPluginService implements AuthPluginService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAuthServiceName() {
|
public String getAuthServiceName() {
|
||||||
return AUTH_PLUGIN_TYPE;
|
return AuthConstants.AUTH_PLUGIN_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNacosAuthManager() {
|
private void checkNacosAuthManager() {
|
||||||
|
@ -23,6 +23,8 @@ package com.alibaba.nacos.plugin.auth.impl.constant;
|
|||||||
*/
|
*/
|
||||||
public class AuthConstants {
|
public class AuthConstants {
|
||||||
|
|
||||||
|
public static final String AUTH_PLUGIN_TYPE = "nacos";
|
||||||
|
|
||||||
public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
|
public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
|
||||||
|
|
||||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
@ -38,4 +40,12 @@ public class AuthConstants {
|
|||||||
public static final String UPDATE_PASSWORD_ENTRY_POINT = CONSOLE_RESOURCE_NAME_PREFIX + "user/password";
|
public static final String UPDATE_PASSWORD_ENTRY_POINT = CONSOLE_RESOURCE_NAME_PREFIX + "user/password";
|
||||||
|
|
||||||
public static final String NACOS_USER_KEY = "nacosuser";
|
public static final String NACOS_USER_KEY = "nacosuser";
|
||||||
|
|
||||||
|
public static final String TOKEN_SECRET_KEY = "token.secret.key";
|
||||||
|
|
||||||
|
public static final String DEFAULT_TOKEN_SECRET_KEY = "";
|
||||||
|
|
||||||
|
public static final String TOKEN_EXPIRE_SECONDS = "token.expire.seconds";
|
||||||
|
|
||||||
|
public static final String DEFAULT_TOKEN_EXPIRE_SECONDS = "18000";
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import com.alibaba.nacos.common.utils.JacksonUtils;
|
|||||||
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
|
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
|
||||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.JwtTokenManager;
|
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.NacosAuthManager;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
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.constant.AuthSystemTypes;
|
||||||
@ -82,6 +83,9 @@ public class UserController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AuthConfigs authConfigs;
|
private AuthConfigs authConfigs;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NacosAuthConfig nacosAuthConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private NacosAuthManager authManager;
|
private NacosAuthManager authManager;
|
||||||
|
|
||||||
@ -214,7 +218,7 @@ public class UserController {
|
|||||||
|
|
||||||
ObjectNode result = JacksonUtils.createEmptyJsonNode();
|
ObjectNode result = JacksonUtils.createEmptyJsonNode();
|
||||||
result.put(Constants.ACCESS_TOKEN, user.getToken());
|
result.put(Constants.ACCESS_TOKEN, user.getToken());
|
||||||
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
|
result.put(Constants.TOKEN_TTL, nacosAuthConfig.getTokenValidityInSeconds());
|
||||||
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
|
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
|
||||||
result.put(Constants.USERNAME, user.getUserName());
|
result.put(Constants.USERNAME, user.getUserName());
|
||||||
return result;
|
return result;
|
||||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.plugin.auth.impl.controller;
|
|||||||
|
|
||||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||||
|
import com.alibaba.nacos.plugin.auth.impl.NacosAuthConfig;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager;
|
import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes;
|
import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes;
|
||||||
import com.alibaba.nacos.plugin.auth.impl.users.NacosUser;
|
import com.alibaba.nacos.plugin.auth.impl.users.NacosUser;
|
||||||
@ -49,6 +50,9 @@ public class UserControllerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private AuthConfigs authConfigs;
|
private AuthConfigs authConfigs;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NacosAuthConfig nacosAuthConfig;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private NacosAuthManager authManager;
|
private NacosAuthManager authManager;
|
||||||
|
|
||||||
@ -65,13 +69,14 @@ public class UserControllerTest {
|
|||||||
user.setToken("1234567890");
|
user.setToken("1234567890");
|
||||||
injectObject("authConfigs", authConfigs);
|
injectObject("authConfigs", authConfigs);
|
||||||
injectObject("authManager", authManager);
|
injectObject("authManager", authManager);
|
||||||
|
injectObject("nacosAuthConfig", nacosAuthConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoginWithAuthedUser() throws AccessException {
|
public void testLoginWithAuthedUser() throws AccessException {
|
||||||
when(authManager.login(request)).thenReturn(user);
|
when(authManager.login(request)).thenReturn(user);
|
||||||
when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name());
|
when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name());
|
||||||
when(authConfigs.getTokenValidityInSeconds()).thenReturn(18000L);
|
when(nacosAuthConfig.getTokenValidityInSeconds()).thenReturn(18000L);
|
||||||
Object actual = userController.login("nacos", "nacos", response, request);
|
Object actual = userController.login("nacos", "nacos", response, request);
|
||||||
assertThat(actual, instanceOf(JsonNode.class));
|
assertThat(actual, instanceOf(JsonNode.class));
|
||||||
String actualString = actual.toString();
|
String actualString = actual.toString();
|
||||||
|
@ -67,6 +67,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-test</artifactId>
|
<artifactId>spring-boot-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.jackson</groupId>
|
||||||
|
<artifactId>jackson-core-asl</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.sys.utils;
|
||||||
|
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties util.
|
||||||
|
*
|
||||||
|
* @author xiweng.yy
|
||||||
|
*/
|
||||||
|
public class PropertiesUtil {
|
||||||
|
|
||||||
|
public static Properties getPropertiesWithPrefix(Environment environment, String prefix)
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
return handleSpringBinder(environment, prefix, Properties.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getPropertiesWithPrefixForMap(Environment environment, String prefix)
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
return handleSpringBinder(environment, prefix, Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle spring binder to bind object.
|
||||||
|
*
|
||||||
|
* @param environment spring environment
|
||||||
|
* @param prefix properties prefix
|
||||||
|
* @param targetClass target class
|
||||||
|
* @param <T> target class
|
||||||
|
* @return binder object
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T handleSpringBinder(Environment environment, String prefix, Class<T> targetClass)
|
||||||
|
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
|
||||||
|
Class<?> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
|
||||||
|
Method getMethod = binderClass.getDeclaredMethod("get", Environment.class);
|
||||||
|
Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class);
|
||||||
|
Object binderObject = getMethod.invoke(null, environment);
|
||||||
|
String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
|
||||||
|
Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass);
|
||||||
|
Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get");
|
||||||
|
return (T) resultGetMethod.invoke(bindResultObject);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.sys.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@ActiveProfiles("prefix")
|
||||||
|
@SpringBootTest(classes = PropertiesUtilTest.class)
|
||||||
|
public class PropertiesUtilTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment environment;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testGetPropertiesWithPrefixForMap()
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||||
|
Map<String, Object> actual = PropertiesUtil.getPropertiesWithPrefixForMap(environment, "nacos.prefix");
|
||||||
|
assertEquals(3, actual.size());
|
||||||
|
for (Map.Entry<String, Object> entry : actual.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Map<String, Object> subMap = (Map<String, Object>) entry.getValue();
|
||||||
|
switch (key) {
|
||||||
|
case "one":
|
||||||
|
assertEquals("1", subMap.get("value"));
|
||||||
|
break;
|
||||||
|
case "two":
|
||||||
|
assertEquals("2", subMap.get("value"));
|
||||||
|
break;
|
||||||
|
case "three":
|
||||||
|
assertEquals("3", subMap.get("value"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPropertiesWithPrefix()
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||||
|
Properties actual = PropertiesUtil.getPropertiesWithPrefix(environment, "nacos.prefix");
|
||||||
|
assertEquals(3, actual.size());
|
||||||
|
}
|
||||||
|
}
|
20
sys/src/test/resources/application-prefix.properties
Normal file
20
sys/src/test/resources/application-prefix.properties
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
nacos.prefix.one.value=1
|
||||||
|
nacos.prefix.two.value=2
|
||||||
|
nacos.prefix.three.value=3
|
||||||
|
nacos.other.prefix.one.value=1
|
Loading…
Reference in New Issue
Block a user