mirror of
https://github.com/Telecominfraproject/wlan-cloud-base.git
synced 2026-03-20 22:39:06 +00:00
Compare commits
15 Commits
AJ
...
WIFI-1054-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92e48ac120 | ||
|
|
e2c1051717 | ||
|
|
5bf56e347a | ||
|
|
b4dd6aa56b | ||
|
|
26ad46c98d | ||
|
|
0f6693b846 | ||
|
|
c2220b8a8f | ||
|
|
aed826fb3a | ||
|
|
41b92eb62e | ||
|
|
3e939d92ce | ||
|
|
eb1a46c745 | ||
|
|
58573cd96e | ||
|
|
1af8228dc4 | ||
|
|
3642cbcf9a | ||
|
|
236cf4f9c2 |
@@ -39,7 +39,13 @@
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>0.3</version>
|
||||
<version>3.11.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>jwks-rsa</artifactId>
|
||||
<version>0.14.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -8,10 +8,51 @@ import java.net.InetAddress;
|
||||
*/
|
||||
public interface ConnectorProperties {
|
||||
|
||||
int getExternalPort();
|
||||
/**
|
||||
* @return port on which this server listens for internal API requests
|
||||
*/
|
||||
int getInternalPort();
|
||||
InetAddress getExternalIpAddress();
|
||||
InetAddress getInternalIpAddress();
|
||||
String getExternalHostName();
|
||||
|
||||
/**
|
||||
* @return host on which this server listens for internal API requests
|
||||
*/
|
||||
String getInternalHostName();
|
||||
|
||||
/**
|
||||
* @return ip address on which this server listens for internal API requests
|
||||
*/
|
||||
InetAddress getInternalIpAddress();
|
||||
|
||||
|
||||
/**
|
||||
* @return port on which this server listens for API requests from the outside world
|
||||
*/
|
||||
int getExternalPort();
|
||||
|
||||
/**
|
||||
* @return host on which this server listens for API requests from the outside world
|
||||
*/
|
||||
String getExternalHostName();
|
||||
|
||||
/**
|
||||
* @return ip address on which this server listens for API requests from the outside world
|
||||
*/
|
||||
InetAddress getExternalIpAddress();
|
||||
|
||||
|
||||
/**
|
||||
* @return port which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer port, or a kubernetes-remapped port
|
||||
*/
|
||||
int getExternallyVisiblePort();
|
||||
|
||||
/**
|
||||
* @return host which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer host, or a kubernetes-remapped host
|
||||
*/
|
||||
String getExternallyVisibleHostName();
|
||||
|
||||
/**
|
||||
* @return ip address which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer ip address, or a kubernetes-remapped ip address
|
||||
*/
|
||||
InetAddress getExternallyVisibleIpAddress();
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,21 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConnectorProperties.class);
|
||||
|
||||
private final int externalPort;
|
||||
//host and port on which this server listens for internal API requests
|
||||
private final int internalPort;
|
||||
private final InetAddress externalIpAddress;
|
||||
private final String internalHostName;
|
||||
private final InetAddress internalIpAddress;
|
||||
|
||||
//host and port on which this server listens for API requests from the outside world
|
||||
private final int externalPort;
|
||||
private final String externalHostName;
|
||||
private final String internalHostName;
|
||||
private final InetAddress externalIpAddress;
|
||||
|
||||
//host and port which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer host and port, or a kubernetes-remapped host/port
|
||||
private final int externallyVisiblePort;
|
||||
private final String externallyVisibleHostName;
|
||||
private final InetAddress externallyVisibleIpAddress;
|
||||
|
||||
public ConnectorPropertiesImpl(Environment environment){
|
||||
|
||||
int _externalPort = Integer.parseInt(environment.getProperty("server.port").trim());
|
||||
@@ -72,26 +79,46 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
|
||||
_internalHostName = _internalIpAddress.getCanonicalHostName();
|
||||
}
|
||||
|
||||
|
||||
//Populate externally-visible properties, if any
|
||||
int _externallyVisiblePort = Integer.parseInt(environment.getProperty("tip.wlan.externallyVisiblePort", "0").trim());
|
||||
if(_externallyVisiblePort == 0) {
|
||||
_externallyVisiblePort = _externalPort;
|
||||
}
|
||||
|
||||
String _externallyVisibleHostName = environment.getProperty("tip.wlan.externallyVisibleHostName");
|
||||
if(_externallyVisibleHostName == null || _externallyVisibleHostName.trim().isEmpty()) {
|
||||
_externallyVisibleHostName = _externalHostName;
|
||||
}
|
||||
|
||||
InetAddress _externallyVisibleIpAddress;
|
||||
String externallyVisibleIpAddrStr = environment.getProperty("tip.wlan.externallyVisibleIpAddress");
|
||||
if(externallyVisibleIpAddrStr == null) {
|
||||
_externallyVisibleIpAddress = _externalIpAddress;
|
||||
} else {
|
||||
try {
|
||||
_externallyVisibleIpAddress = InetAddress.getByName(externallyVisibleIpAddrStr.trim());
|
||||
} catch (UnknownHostException e) {
|
||||
throw new ConfigurationException("Cannot get externally visible address of the system", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.externalIpAddress = _externalIpAddress;
|
||||
this.externalHostName = _externalHostName;
|
||||
this.externalPort = _externalPort;
|
||||
|
||||
this.internalIpAddress = _internalIpAddress;
|
||||
this.internalHostName = _internalHostName;
|
||||
this.internalPort = _internalPort;
|
||||
|
||||
this.externallyVisibleIpAddress = _externallyVisibleIpAddress;
|
||||
this.externallyVisibleHostName = _externallyVisibleHostName;
|
||||
this.externallyVisiblePort = _externallyVisiblePort;
|
||||
|
||||
LOG.info("connectorProperties {}", this);
|
||||
}
|
||||
|
||||
public ConnectorPropertiesImpl(String externalHostName, InetAddress externalIpAddress, int externalPort,
|
||||
String internalHostName, InetAddress internalIpAddress, int internalPort) {
|
||||
this.externalIpAddress = externalIpAddress;
|
||||
this.externalHostName = externalHostName;
|
||||
this.externalPort = externalPort;
|
||||
this.internalIpAddress = internalIpAddress;
|
||||
this.internalHostName = internalHostName;
|
||||
this.internalPort = internalPort;
|
||||
}
|
||||
|
||||
public int getExternalPort() {
|
||||
return externalPort;
|
||||
@@ -117,24 +144,24 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
|
||||
return internalHostName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("ConnectorProperties [externalHostName=");
|
||||
builder.append(externalHostName);
|
||||
builder.append(", externalIpAddress=");
|
||||
builder.append(externalIpAddress);
|
||||
builder.append(", externalPort=");
|
||||
builder.append(externalPort);
|
||||
builder.append(", internalHostName=");
|
||||
builder.append(internalHostName);
|
||||
builder.append(", internalIpAddress=");
|
||||
builder.append(internalIpAddress);
|
||||
builder.append(", internalPort=");
|
||||
builder.append(internalPort);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
public int getExternallyVisiblePort() {
|
||||
return externallyVisiblePort;
|
||||
}
|
||||
|
||||
public String getExternallyVisibleHostName() {
|
||||
return externallyVisibleHostName;
|
||||
}
|
||||
|
||||
public InetAddress getExternallyVisibleIpAddress() {
|
||||
return externallyVisibleIpAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"ConnectorPropertiesImpl [internalPort=%s, internalHostName=%s, internalIpAddress=%s, externalPort=%s, externalHostName=%s, externalIpAddress=%s, externallyVisiblePort=%s, externallyVisibleHostName=%s, externallyVisibleIpAddress=%s]",
|
||||
internalPort, internalHostName, internalIpAddress, externalPort, externalHostName, externalIpAddress,
|
||||
externallyVisiblePort, externallyVisibleHostName, externallyVisibleIpAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -871,21 +871,23 @@ public abstract class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
protected Auth0AuthenticationProvider createAuth0AuthenticationProvider(int providerIndex) throws Exception {
|
||||
String clientId;
|
||||
String clientSecret;
|
||||
String securedRoute;
|
||||
String issuer;
|
||||
String accessTypeValue;
|
||||
String jwksLocation;
|
||||
if (0 == providerIndex) {
|
||||
clientId = environment.getProperty("tip.wlan.auth0.clientId", DEFAULT_AUTH0_PROPERTY);
|
||||
clientSecret = environment.getProperty("tip.wlan.auth0.clientSecret", DEFAULT_AUTH0_PROPERTY);
|
||||
securedRoute = environment.getProperty("tip.wlan.auth0.securedRoute", DEFAULT_AUTH0_PROPERTY);
|
||||
issuer = environment.getProperty("tip.wlan.auth0.issuerUri", DEFAULT_AUTH0_PROPERTY);
|
||||
accessTypeValue = environment.getProperty("tip.wlan.auth0.accessType",
|
||||
getDefaultAccessType(providerIndex));
|
||||
jwksLocation = environment.getProperty("tip.wlan.auth0.jwksLocation", DEFAULT_AUTH0_PROPERTY);
|
||||
} else {
|
||||
clientId = environment.getProperty("tip.wlan.auth0.clientId" + providerIndex);
|
||||
clientSecret = environment.getProperty("tip.wlan.auth0.clientSecret" + providerIndex);
|
||||
securedRoute = environment.getProperty("tip.wlan.auth0.securedRoute" + providerIndex,
|
||||
DEFAULT_AUTH0_PROPERTY);
|
||||
issuer = environment.getProperty("tip.wlan.auth0.issuer" + providerIndex);
|
||||
accessTypeValue = environment.getProperty("tip.wlan.auth0.accessType" + providerIndex,
|
||||
getDefaultAccessType(providerIndex));
|
||||
jwksLocation = environment.getProperty("tip.wlan.auth0.jwksLocation" + providerIndex);
|
||||
}
|
||||
if (null == clientId) {
|
||||
return null;
|
||||
@@ -896,7 +898,8 @@ public abstract class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
Auth0AuthenticationProvider auth0Provider = new Auth0AuthenticationProvider(accessType);
|
||||
auth0Provider.setClientId(clientId);
|
||||
auth0Provider.setClientSecret(clientSecret);
|
||||
auth0Provider.setSecuredRoute(securedRoute);
|
||||
auth0Provider.setIssuer(issuer);
|
||||
auth0Provider.setJwksLocation(jwksLocation);
|
||||
auth0Provider.afterPropertiesSet();
|
||||
LOG.info("Loaded configuration for auth0 provider {}", providerIndex);
|
||||
return auth0Provider;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.telecominfraproject.wlan.core.server.security.auth0;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SignatureException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
@@ -13,8 +16,20 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import com.auth0.jwk.Jwk;
|
||||
import com.auth0.jwk.JwkException;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.telecominfraproject.wlan.core.server.security.AccessType;
|
||||
import com.telecominfraproject.wlan.server.exceptions.ConfigurationException;
|
||||
|
||||
@@ -23,18 +38,21 @@ import com.telecominfraproject.wlan.server.exceptions.ConfigurationException;
|
||||
* the userdetails in the authentication object
|
||||
*
|
||||
* @author Daniel Teixeira
|
||||
* @author rlee
|
||||
*/
|
||||
public class Auth0AuthenticationProvider implements AuthenticationProvider, InitializingBean {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Auth0AuthenticationProvider.class);
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private JWTVerifier jwtVerifier = null;
|
||||
private String clientSecret = null;
|
||||
private String clientId = null;
|
||||
private String securedRoute = null;
|
||||
private String issuer = null;
|
||||
private String jwksLocation = null;
|
||||
private final AccessType accessType;
|
||||
private static final AuthenticationException AUTH_ERROR = new Auth0TokenException("Authentication error occured");
|
||||
|
||||
|
||||
public Auth0AuthenticationProvider(AccessType accessType) {
|
||||
this.accessType = accessType;
|
||||
}
|
||||
@@ -42,35 +60,52 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
|
||||
String token = ((Auth0JWTToken) authentication).getJwt();
|
||||
|
||||
LOG.trace("Auth0 trying to authenticate with token: {} ", token);
|
||||
|
||||
Map<String, Object> decoded;
|
||||
|
||||
try {
|
||||
|
||||
Auth0JWTToken tokenAuth = ((Auth0JWTToken) authentication);
|
||||
decoded = jwtVerifier.verify(token);
|
||||
LOG.trace("Decoded JWT token {}", decoded);
|
||||
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
String alg = jwt.getAlgorithm();
|
||||
|
||||
// Get jwks file
|
||||
Jwk jwk = getJwk(jwt.getKeyId());
|
||||
if (jwk == null) {
|
||||
throw new JwkException("jwk could not be found");
|
||||
}
|
||||
|
||||
Algorithm algorithm;
|
||||
if (alg.equals("RS256")) {
|
||||
// create RS256 key decoder
|
||||
algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
|
||||
} else {
|
||||
// create HS256 key decoder
|
||||
algorithm = Algorithm.HMAC256(clientSecret);
|
||||
}
|
||||
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withIssuer(issuer)
|
||||
.build();
|
||||
|
||||
jwt = verifier.verify(token);
|
||||
LOG.trace("Decoded JWT token {}", jwt);
|
||||
tokenAuth.setAuthenticated(true);
|
||||
tokenAuth.setPrincipal(new Auth0UserDetails(decoded, this.accessType));
|
||||
tokenAuth.setDetails(decoded);
|
||||
tokenAuth.setPrincipal(new Auth0UserDetails(jwt, this.accessType));
|
||||
tokenAuth.setDetails(jwt);
|
||||
return authentication;
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
LOG.error("InvalidKeyException thrown while decoding JWT token", e);
|
||||
} catch (JWTDecodeException e) {
|
||||
LOG.error("JWTDecodeException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
LOG.error("NoSuchAlgorithmException thrown while decoding JWT token", e);
|
||||
} catch (JWTVerificationException e) {
|
||||
LOG.error("JWTVerificationException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (JwkException e) {
|
||||
LOG.error("JwkException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (IllegalStateException e) {
|
||||
LOG.error("IllegalStateException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (SignatureException e) {
|
||||
LOG.debug("SignatureException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,21 +114,84 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if ((clientSecret == null) || (clientId == null)) {
|
||||
throw new ConfigurationException("Client secret or client id is not set for Auth0AuthenticationProvider");
|
||||
if ((clientSecret == null) || (clientId == null) || (issuer == null)) {
|
||||
throw new ConfigurationException("Client secret, client id, or issuer URI is not set for Auth0AuthenticationProvider");
|
||||
}
|
||||
if (securedRoute == null) {
|
||||
throw new ConfigurationException("SecureRoute is not set for Auth0AuthenticationProvider");
|
||||
}
|
||||
jwtVerifier = new JWTVerifier(clientSecret, clientId);
|
||||
}
|
||||
|
||||
public String getSecuredRoute() {
|
||||
return securedRoute;
|
||||
|
||||
private Jwk getJwk(String keyId) {
|
||||
try {
|
||||
String jwksSource = getJwksString();
|
||||
if (jwksSource == null) {
|
||||
throw new FileNotFoundException("jwks could not be found");
|
||||
}
|
||||
|
||||
List<Jwk> jwks = Lists.newArrayList();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> keys = (List<Map<String, Object>>) mapper.readValue(jwksSource, Map.class).get("keys");
|
||||
|
||||
for (Map<String, Object> values : keys) {
|
||||
jwks.add(Jwk.fromValues(values));
|
||||
}
|
||||
|
||||
if (keyId == null && jwks.size() == 1) {
|
||||
return jwks.get(0);
|
||||
}
|
||||
|
||||
if (keyId != null) {
|
||||
for (Jwk jwk : jwks) {
|
||||
if (keyId.equals(jwk.getId())) {
|
||||
// Can only contain 1 matching jwk
|
||||
return jwk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JsonMappingException e) {
|
||||
LOG.error("JsonMappingException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (JsonProcessingException e) {
|
||||
LOG.error("JsonProcessingException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (FileNotFoundException e) {
|
||||
LOG.error("FileNotFoundException thrown while decoding JWT token", e);
|
||||
throw AUTH_ERROR;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSecuredRoute(String securedRoute) {
|
||||
this.securedRoute = securedRoute;
|
||||
|
||||
private String getJwksString() {
|
||||
LOG.debug("Loading jwks from {}", jwksLocation);
|
||||
String ret = null;
|
||||
|
||||
try {
|
||||
Object jwksObj = ResourceUtils.getURL(jwksLocation).getContent();
|
||||
if (jwksObj instanceof InputStream) {
|
||||
ret = readFromInputStream((InputStream) jwksObj);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
LOG.error("FileNotFoundException thrown while getting jwks", e);
|
||||
throw AUTH_ERROR;
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException thrown while getting jwks", e);
|
||||
throw AUTH_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String readFromInputStream(InputStream inputStream) {
|
||||
StringBuilder resultStringBuilder = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
resultStringBuilder.append(line).append("\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException thrown while getting jwks", e);
|
||||
throw AUTH_ERROR;
|
||||
}
|
||||
return resultStringBuilder.toString();
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
@@ -111,6 +209,22 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
public void setIssuer(String issuer) {
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
public String getJwksLocation() {
|
||||
return jwksLocation;
|
||||
}
|
||||
|
||||
public void setJwksLocation(String jwksLocation) {
|
||||
this.jwksLocation = jwksLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to encode raw secret to Base 64 URL safe string
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.telecominfraproject.wlan.core.server.security.auth0;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -10,6 +9,7 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.telecominfraproject.wlan.core.server.security.AccessType;
|
||||
import com.telecominfraproject.wlan.core.server.security.AuthProviderInfo;
|
||||
|
||||
@@ -24,42 +24,46 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
|
||||
|
||||
private static final long serialVersionUID = 2058797193125711681L;
|
||||
|
||||
private Map<String, Object> details;
|
||||
private DecodedJWT details;
|
||||
private String username;
|
||||
private boolean emailVerified = false;
|
||||
private Collection<GrantedAuthority> authorities = null;
|
||||
private final AccessType accessType;
|
||||
private static final String EMAIL_CLAIM = "email";
|
||||
private static final String EMAIL_VERIFIED_CLAIM = "email_verified";
|
||||
private static final String NICKNAME_CLAIM = "nickname";
|
||||
private static final String ROLES_CLAIM = "roles";
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(Auth0UserDetails.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Auth0UserDetails(Map<String, Object> map, AccessType accessType) {
|
||||
public Auth0UserDetails(DecodedJWT jwt, AccessType accessType) {
|
||||
this.accessType = accessType;
|
||||
if (map.containsKey("email")) {
|
||||
this.username = map.get("email").toString();
|
||||
} else if (map.containsKey("username")) {
|
||||
this.username = map.get("username").toString();
|
||||
} else if (map.containsKey("user_id")) {
|
||||
this.username = map.get("user_id").toString();
|
||||
if (!jwt.getClaim(EMAIL_CLAIM).isNull()) {
|
||||
this.username = jwt.getClaim(EMAIL_CLAIM).asString();
|
||||
} else if (!jwt.getClaim(NICKNAME_CLAIM).isNull()) {
|
||||
this.username = jwt.getClaim(NICKNAME_CLAIM).asString();
|
||||
} else if (jwt.getId() != null) {
|
||||
this.username = jwt.getId();
|
||||
} else if (jwt.getSubject() != null) {
|
||||
this.username = jwt.getSubject();
|
||||
} else {
|
||||
this.username = "UNKNOWN_USER";
|
||||
}
|
||||
|
||||
if (map.containsKey("email")) {
|
||||
this.emailVerified = Boolean.valueOf(map.get("email_verified").toString());
|
||||
if (!jwt.getClaim(EMAIL_CLAIM).isNull()) {
|
||||
this.emailVerified = Boolean.valueOf(jwt.getClaim(EMAIL_VERIFIED_CLAIM).toString());
|
||||
}
|
||||
|
||||
// set authorities
|
||||
authorities = new ArrayList<>();
|
||||
if (map.containsKey("roles")) {
|
||||
if (!jwt.getClaim(ROLES_CLAIM).isNull()) {
|
||||
ArrayList<String> roles = null;
|
||||
try {
|
||||
roles = (ArrayList<String>) map.get("roles");
|
||||
roles = (ArrayList<String>) jwt.getClaim(ROLES_CLAIM).asList(String.class);
|
||||
for (String role : roles) {
|
||||
authorities.add(new SimpleGrantedAuthority(role));
|
||||
}
|
||||
} catch (java.lang.ClassCastException e) {
|
||||
// e.printStackTrace();
|
||||
LOGGER.error("Error in casting the roles object", e);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +73,7 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
|
||||
this.details = map;
|
||||
this.details = jwt;
|
||||
|
||||
}
|
||||
|
||||
@@ -128,7 +132,11 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
|
||||
* otherwise
|
||||
*/
|
||||
public Object getAuth0Attribute(String attributeName) {
|
||||
return details.get(attributeName);
|
||||
if (details.getClaim(attributeName).isNull()) {
|
||||
LOGGER.debug("No attribute was found : " + attributeName);
|
||||
return null;
|
||||
}
|
||||
return details.getClaim(attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
package com.telecominfraproject.wlan.core.server.security.auth0.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SignatureException;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.auth0.jwt.Algorithm;
|
||||
import com.auth0.jwt.ClaimSet;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwk.Jwk;
|
||||
import com.auth0.jwk.JwkException;
|
||||
import com.auth0.jwk.JwkProvider;
|
||||
import com.auth0.jwk.UrlJwkProvider;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.JwtSigner;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.telecominfraproject.wlan.core.server.security.auth0.Auth0TokenHelper;
|
||||
@@ -25,26 +27,23 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
|
||||
private static final Log Logger = LogFactory.getLog(Auth0TokenHelperImpl.class);
|
||||
|
||||
private String clientSecret = null;
|
||||
private String clientId = null;
|
||||
private String issuer = null;
|
||||
|
||||
@Override
|
||||
public String generateToken(Object object, int expiration) {
|
||||
|
||||
String payload, token;
|
||||
String token;
|
||||
try {
|
||||
|
||||
JwtSigner jwtSigner = new JwtSigner();
|
||||
payload = new ObjectMapper().writeValueAsString(object);
|
||||
|
||||
ClaimSet claimSet = new ClaimSet();
|
||||
claimSet.setExp(expiration); // expire in 1 year
|
||||
|
||||
token = jwtSigner.encode(Algorithm.HS256, payload, "payload", new String(Base64.decodeBase64(clientSecret)), claimSet);
|
||||
|
||||
Algorithm hsEncoded = Algorithm.HMAC256(clientSecret);
|
||||
token = JWT.create()
|
||||
.withIssuer(issuer)
|
||||
.withExpiresAt(new Date(expiration))
|
||||
.withClaim("payload", new ObjectMapper().writeValueAsString(object))
|
||||
.sign(hsEncoded);
|
||||
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
}
|
||||
|
||||
return token;
|
||||
@@ -53,39 +52,43 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
|
||||
|
||||
@Override
|
||||
public Object decodeToken(String token) {
|
||||
|
||||
JWTVerifier jwtVerifier = new JWTVerifier(clientSecret, clientId);
|
||||
|
||||
|
||||
Map<String, Object> verify;
|
||||
JwkProvider jwkProvider = new UrlJwkProvider(issuer);
|
||||
|
||||
try {
|
||||
|
||||
verify = jwtVerifier.verify(token);
|
||||
String payload = (String) verify.get("$");
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
String alg = jwt.getAlgorithm();
|
||||
|
||||
// Get jwk
|
||||
Jwk jwk = jwkProvider.get(jwt.getKeyId());
|
||||
|
||||
Algorithm algorithm;
|
||||
if (alg.equals("RS256")) {
|
||||
// create RS256 key decoder
|
||||
algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
|
||||
} else {
|
||||
// create HS256 key decoder
|
||||
algorithm = Algorithm.HMAC256(clientSecret);
|
||||
}
|
||||
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withIssuer(issuer)
|
||||
.build();
|
||||
|
||||
jwt = verifier.verify(token);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = new ObjectMapper().readValue(payload, Map.class);
|
||||
Map<String, String> map = new ObjectMapper().readValue(jwt.getPayload(), Map.class);
|
||||
return map;
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
} catch (IllegalStateException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
} catch (SignatureException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
} catch (IllegalStateException|IOException|JwkException e) {
|
||||
throw new Auth0RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(clientSecret, "The client secret is not set for " + this.getClass());
|
||||
Assert.notNull(clientId, "The client id is not set for " + this.getClass());
|
||||
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
@@ -96,12 +99,4 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.telecominfraproject.wlan.core.model.equipment;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
|
||||
|
||||
public abstract class AbstractSource<T> extends BaseJsonModel {
|
||||
private static final long serialVersionUID = 2761981826629575941L;
|
||||
protected SourceType source;
|
||||
protected T value;
|
||||
|
||||
public AbstractSource(SourceType source, T manualValue) {
|
||||
this.source = source;
|
||||
this.value = manualValue;
|
||||
}
|
||||
|
||||
protected AbstractSource() {
|
||||
// json construct
|
||||
}
|
||||
|
||||
public SourceType getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(SourceType source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(source, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof AbstractSource)) {
|
||||
return false;
|
||||
}
|
||||
AbstractSource<T> other = (AbstractSource<T>) obj;
|
||||
return this.source == other.source && Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.telecominfraproject.wlan.core.model.equipment;
|
||||
|
||||
public class SourceSelectionSteering extends AbstractSource<RadioBestApSettings>{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4631172351117490997L;
|
||||
|
||||
private SourceSelectionSteering() {
|
||||
|
||||
}
|
||||
|
||||
private SourceSelectionSteering(SourceType source, RadioBestApSettings value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionSteering createAutomaticInstance(RadioBestApSettings value) {
|
||||
return new SourceSelectionSteering(SourceType.auto, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionSteering createManualInstance(RadioBestApSettings value) {
|
||||
return new SourceSelectionSteering(SourceType.manual, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionSteering createProfileInstance(RadioBestApSettings value) {
|
||||
return new SourceSelectionSteering(SourceType.profile, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnsupportedValue() {
|
||||
if (SourceType.isUnsupported(source)) {
|
||||
return true;
|
||||
}
|
||||
if ((null != value) && value.hasUnsupportedValue()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.telecominfraproject.wlan.core.model.equipment;
|
||||
|
||||
public class SourceSelectionValue extends AbstractSource<Integer>{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4631172351117490997L;
|
||||
|
||||
private SourceSelectionValue() {
|
||||
|
||||
}
|
||||
|
||||
private SourceSelectionValue(SourceType source, int value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionValue createAutomaticInstance(int value) {
|
||||
return new SourceSelectionValue(SourceType.auto, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionValue createManualInstance(int value) {
|
||||
return new SourceSelectionValue(SourceType.manual, value);
|
||||
}
|
||||
|
||||
public static SourceSelectionValue createProfileInstance(int value) {
|
||||
return new SourceSelectionValue(SourceType.profile, value);
|
||||
}
|
||||
|
||||
public static AutoOrManualValue getAutoOrManualFromSourcedValue(SourceSelectionValue param) {
|
||||
AutoOrManualValue ret = null;
|
||||
if (param.getSource() == SourceType.auto) {
|
||||
ret = AutoOrManualValue.createAutomaticInstance(param.getValue());
|
||||
} else if (param.getSource() == SourceType.profile) {
|
||||
ret = AutoOrManualValue.createManualInstance(param.getValue());
|
||||
} else { // else param.getSource == SourceType.manual
|
||||
ret = AutoOrManualValue.createManualInstance(param.getValue());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnsupportedValue() {
|
||||
if (SourceType.isUnsupported(source)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.telecominfraproject.wlan.core.model.equipment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.telecominfraproject.wlan.core.model.json.JsonDeserializationUtils;
|
||||
|
||||
public enum SourceType {
|
||||
|
||||
auto(0L),
|
||||
manual(1L),
|
||||
profile(2L),
|
||||
|
||||
UNSUPPORTED(-1L);
|
||||
|
||||
private final long id;
|
||||
private static final Map<Long, SourceType> ELEMENTS = new HashMap<>();
|
||||
|
||||
private SourceType(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static SourceType getById(long enumId) {
|
||||
if (ELEMENTS.isEmpty()) {
|
||||
synchronized (ELEMENTS) {
|
||||
if (ELEMENTS.isEmpty()) {
|
||||
//initialize elements map
|
||||
for(SourceType met : SourceType.values()) {
|
||||
ELEMENTS.put(met.getId(), met);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ELEMENTS.get(enumId);
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static SourceType getByName(String value) {
|
||||
return JsonDeserializationUtils.deserializEnum(value, SourceType.class, UNSUPPORTED);
|
||||
}
|
||||
|
||||
public static boolean isUnsupported(SourceType value) {
|
||||
return UNSUPPORTED.equals(value);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ public class WebTokenRequest extends BaseJsonModel {
|
||||
private String grantType;
|
||||
private String userId;
|
||||
private String password;
|
||||
private String refreshToken;
|
||||
private String scope;
|
||||
|
||||
public String getGrantType() {
|
||||
@@ -39,5 +40,11 @@ public class WebTokenRequest extends BaseJsonModel {
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public class WebTokenResult extends BaseJsonModel {
|
||||
private boolean resetPassword;
|
||||
private String access_token;
|
||||
private String refresh_token;
|
||||
private String id_token;
|
||||
private String token_type;
|
||||
private int expires_in;
|
||||
private int idle_timeout;
|
||||
@@ -43,6 +44,12 @@ public class WebTokenResult extends BaseJsonModel {
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
public String getId_token() {
|
||||
return id_token;
|
||||
}
|
||||
public void setId_token(String id_token) {
|
||||
this.id_token = id_token;
|
||||
}
|
||||
public String getToken_type() {
|
||||
return token_type;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.telecominfraproject.wlan.remote.tests;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@@ -28,6 +29,8 @@ import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.SimpleTransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import com.telecominfraproject.wlan.server.RemoteTestServer;
|
||||
|
||||
@@ -139,20 +142,36 @@ public abstract class BaseRemoteTest {
|
||||
@Override
|
||||
public void rollback(TransactionStatus status) throws TransactionException {
|
||||
LOG.info("Simulating Rollback for {}", status);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(TransactionStatus status) throws TransactionException {
|
||||
LOG.info("Simulating Commit for {}", status);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager
|
||||
.getSynchronizations();
|
||||
if (synchronizations != null) {
|
||||
for (TransactionSynchronization synchronization : synchronizations) {
|
||||
synchronization.afterCommit();
|
||||
}
|
||||
}
|
||||
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
|
||||
LOG.info("Simulating getTransaction for {}", definition);
|
||||
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
}
|
||||
TransactionStatus ts = new SimpleTransactionStatus();
|
||||
return ts;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return ptm;
|
||||
|
||||
Reference in New Issue
Block a user