Added option to define project for admin user

Change-Id: I5f0830150d47596d257c5034a32030af0309f720
This commit is contained in:
Ryan Brandt 2015-03-10 12:39:14 -06:00
parent cdd502e6a3
commit 74821d2b17
3 changed files with 226 additions and 190 deletions

View File

@ -244,5 +244,6 @@ public interface AuthConstants {
public static final String ADMIN_ACCESS_KEY = "AdminAccessKey";
public static final String ADMIN_SECRET_KEY = "AdminSecretKey";
public static final String ADMIN_PROJECT_ID = "AdminProjectId";
public static final String ADMIN_PROJECT_NAME = "AdminProjectName";
}

View File

@ -58,6 +58,7 @@ public class Config implements AuthConstants {
// configuration for admin default project
private String adminProjectId;
private String adminProjectName;
// flag to indicate if the filter is already intialized with required parameters
private volatile boolean initialized = false;
@ -105,6 +106,7 @@ public class Config implements AuthConstants {
includeCatalog = getValue(INCLUDE_SERVICE_CATALOG, true);
adminAuthMethod = getValue(ADMIN_AUTH_METHOD, "");
adminProjectId = getValue(ADMIN_PROJECT_ID, "");
adminProjectName = getValue(ADMIN_PROJECT_NAME, "");
timeToCacheToken = getValue(TIME_TO_CACHE_TOKEN, 600);
long maxTokenCacheSize = getValue(MAX_TOKEN_CACHE_SIZE, 1048576);
@ -137,10 +139,14 @@ public class Config implements AuthConstants {
return initialized;
}
protected String getAdminProject() {
protected String getAdminProjectId() {
return adminProjectId;
}
protected String getAdminProjectName(){
return adminProjectName;
}
protected String getAdminAccessKey() {
if (context.getAttribute(ADMIN_ACCESS_KEY) != null) {
return (String) context.getAttribute(ADMIN_ACCESS_KEY);

View File

@ -46,235 +46,264 @@ import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
public class HttpAuthClient implements AuthClient {
private static final Logger logger = LoggerFactory.getLogger(HttpAuthClient.class);
private static final int DELTA_TIME_IN_SEC = 30;
private static SimpleDateFormat expiryFormat;
static {
expiryFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
expiryFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private final Config appConfig = Config.getInstance();
private static final Logger logger = LoggerFactory.getLogger(HttpAuthClient.class);
private HttpClient client;
private String adminToken;
private String adminTokenExpiry;
private URI uri;
private static final int DELTA_TIME_IN_SEC = 30;
private static SimpleDateFormat expiryFormat;
public HttpAuthClient(HttpClient client, URI uri) {
this.client = client;
static {
expiryFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
expiryFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private final Config appConfig = Config.getInstance();
private HttpClient client;
private String adminToken;
private String adminTokenExpiry;
private URI uri;
public HttpAuthClient(HttpClient client, URI uri) {
this.client = client;
this.uri = uri;
}
@Override
public String validateTokenForServiceEndpointV3(String token) throws ClientProtocolException {
String newUri = uri.toString() + "/v3/auth/tokens/";
Header[] header = new Header[1];
header[0] = new BasicHeader(AUTH_SUBJECT_TOKEN, token);
return verifyUUIDToken(token, newUri, header);
}
@Override
public String validateTokenForServiceEndpointV3(String token) throws ClientProtocolException {
String newUri = uri.toString() + "/v3/auth/tokens/";
Header[] header = new Header[1];
header[0] = new BasicHeader(AUTH_SUBJECT_TOKEN, token);
return verifyUUIDToken(token, newUri, header);
}
private String verifyUUIDToken(String token, String newUri,
Header[] header)
throws ClientProtocolException {
HttpResponse response = sendGet(newUri, header);
private String verifyUUIDToken(String token, String newUri,
Header[] header)
throws ClientProtocolException {
HttpResponse response = sendGet(newUri, header);
HttpEntity entity = response.getEntity();
int code = response.getStatusLine().getStatusCode();
InputStream instream = null;
try {
if (code == 404) {
instream = entity.getContent();
instream.close();
throw new AuthException("Authorization failed for user token: " + token);
}
if (code != 200) {
adminToken = null;
instream = entity.getContent();
instream.close();
String reasonPhrase = response.getStatusLine().getReasonPhrase();
throw new AuthException("Failed to validate via HTTP " + code
+ " " + reasonPhrase);
}
} catch(IOException e) {
throw new ClientProtocolException(
"IO Exception: problem closing stream ", e);
InputStream instream = null;
try {
if (code == 404) {
instream = entity.getContent();
instream.close();
throw new AuthException("Authorization failed for user token: " + token);
}
if (code != 200) {
adminToken = null;
instream = entity.getContent();
instream.close();
String reasonPhrase = response.getStatusLine().getReasonPhrase();
return parseResponse(response);
}
throw new AuthException("Failed to validate via HTTP " + code
+ " " + reasonPhrase);
}
} catch (IOException e) {
throw new ClientProtocolException(
"IO Exception: problem closing stream ", e);
}
private HttpResponse sendPost(String uri, StringEntity body)
throws ClientProtocolException {
HttpResponse response = null;
HttpPost post = new HttpPost(uri);
post.setHeader("Accept", "application/json");
post.setHeader("Content-Type", "application/json");
try {
post.setEntity(body);
response = client.execute(post);
return parseResponse(response);
}
private HttpResponse sendPost(String uri, StringEntity body)
throws ClientProtocolException {
HttpResponse response = null;
HttpPost post = new HttpPost(uri);
post.setHeader("Accept", "application/json");
post.setHeader("Content-Type", "application/json");
try {
post.setEntity(body);
response = client.execute(post);
int code = response.getStatusLine().getStatusCode();
if (!(code == 201 || code == 200 || code == 203)) {
adminToken = null;
throw new AdminAuthException(
"Failed to authenticate admin credentials " + code
+ response.getStatusLine().getReasonPhrase());
}
} catch (IOException e) {
final String message;
if ((e.getMessage() == null) && (e.getCause() != null)) {
message = e.getCause().getMessage();
}
else {
message = e.getMessage();
}
logger.error("Failure authenticating adminUser: {}", message);
post.abort();
throw new AdminAuthException(
"Failure authenticating adminUser :" + message, e);
}
return response;
}
if (!(code == 201 || code == 200 || code == 203)) {
adminToken = null;
throw new AdminAuthException(
"Failed to authenticate admin credentials " + code
+ response.getStatusLine().getReasonPhrase());
}
} catch (IOException e) {
final String message;
if ((e.getMessage() == null) && (e.getCause() != null)) {
message = e.getCause().getMessage();
} else {
message = e.getMessage();
}
logger.error("Failure authenticating adminUser: {}", message);
post.abort();
throw new AdminAuthException(
"Failure authenticating adminUser :" + message, e);
}
return response;
}
private HttpResponse sendGet(String newUri, Header[] headers)
throws ClientProtocolException {
HttpResponse response = null;
HttpGet get = null;
private HttpResponse sendGet(String newUri, Header[] headers)
throws ClientProtocolException {
HttpResponse response = null;
HttpGet get = null;
get = new HttpGet(newUri);
get.setHeader("Accept", "application/json");
get.setHeader("Content-Type", "application/json");
if (headers != null) {
for (Header header : headers) {
get.setHeader(header);
}
}
get = new HttpGet(newUri);
get.setHeader("Accept", "application/json");
get.setHeader("Content-Type", "application/json");
if (headers != null) {
for (Header header : headers) {
get.setHeader(header);
}
}
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.TOKEN)) {
get.setHeader(new BasicHeader(TOKEN, appConfig.getAdminToken()));
}
else {
get.setHeader(new BasicHeader(TOKEN, getAdminToken()));
}
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.TOKEN)) {
get.setHeader(new BasicHeader(TOKEN, appConfig.getAdminToken()));
} else {
get.setHeader(new BasicHeader(TOKEN, getAdminToken()));
}
try {
response = client.execute(get);
try {
response = client.execute(get);
}catch(ConnectException c) {
} catch (ConnectException c) {
get.abort();
throw new ServiceUnavailableException(c.getMessage());
}
catch (IOException e) {
get.abort();
} catch (IOException e) {
get.abort();
throw new ClientProtocolException(
"IO Exception during GET request ", e);
}
"IO Exception during GET request ", e);
}
return response;
}
}
private String parseResponse(HttpResponse response) {
StringBuffer json = new StringBuffer();
private String parseResponse(HttpResponse response) {
StringBuffer json = new StringBuffer();
HttpEntity entity = response.getEntity();
if (entity != null) {
if (entity != null) {
InputStream instream;
try {
try {
instream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(instream));
String line = reader.readLine();
while (line != null) {
json.append(line);
line = reader.readLine();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(instream));
String line = reader.readLine();
while (line != null) {
json.append(line);
line = reader.readLine();
}
instream.close();
reader.close();
} catch (Exception e) {
throw new AuthException("Failed to parse Http Response ", e);
}
}
} catch (Exception e) {
throw new AuthException("Failed to parse Http Response ", e);
}
}
return json.toString();
}
}
private String getAdminToken() throws ClientProtocolException {
HttpResponse response;
String json;
JsonParser jp = new JsonParser();
private String getAdminToken() throws ClientProtocolException {
HttpResponse response;
String json;
JsonParser jp = new JsonParser();
if (adminTokenExpiry != null) {
if (isExpired(adminTokenExpiry)) {
adminToken = null;
}
}
if (adminToken == null) {
StringEntity params = getUnscopedV3AdminTokenRequest();
String authUri = uri + "/v3/auth/tokens";
response = sendPost(authUri, params);
adminToken = response.getFirstHeader(AUTH_SUBJECT_TOKEN).getValue();
json = parseResponse(response);
JsonObject token = jp.parse(json).getAsJsonObject().get("token").getAsJsonObject();
adminTokenExpiry = token.get("expires_at").getAsString();
}
return adminToken;
}
if (adminTokenExpiry != null) {
if (isExpired(adminTokenExpiry)) {
adminToken = null;
}
}
if (adminToken == null) {
StringEntity params = getUnscopedV3AdminTokenRequest();
String authUri = uri + "/v3/auth/tokens";
response = sendPost(authUri, params);
adminToken = response.getFirstHeader(AUTH_SUBJECT_TOKEN).getValue();
json = parseResponse(response);
JsonObject token = jp.parse(json).getAsJsonObject().get("token").getAsJsonObject();
adminTokenExpiry = token.get("expires_at").getAsString();
}
return adminToken;
}
private String buildAuth(final String userName, final String password) {
final JsonObject domain = new JsonObject();
domain.addProperty("id", "default");
final JsonObject user = new JsonObject();
user.addProperty("name", userName);
user.addProperty("password", password);
user.add("domain", domain);
final JsonArray methods = new JsonArray();
final JsonObject passwordHolder = new JsonObject();
passwordHolder.add("user", user);
methods.add(new JsonPrimitive("password"));
final JsonObject identity = new JsonObject();
identity.add("methods", methods);
identity.add("password", passwordHolder);
final JsonObject auth = new JsonObject();
auth.add("identity", identity);
final JsonObject outer = new JsonObject();
outer.add("auth", auth);
return outer.toString();
}
private String buildAuth(final String userName, final String password,
final String projectId, final String projectName) {
final JsonObject domain = new JsonObject();
domain.addProperty("id", "default");
private StringEntity getUnscopedV3AdminTokenRequest() {
final String body;
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.PASSWORD)) {
body = buildAuth(appConfig.getAdminUser(), appConfig.getAdminPassword());
} else {
String msg = String.format("Admin auth method %s not supported",appConfig.getAdminAuthMethod());
throw new AdminAuthException(msg);
}
try {
return new StringEntity(body);
} catch (UnsupportedEncodingException e) {
throw new AdminAuthException("Invalid V3 authentication request " + e);
}
}
final JsonObject user = new JsonObject();
user.addProperty("name", userName);
user.addProperty("password", password);
user.add("domain", domain);
private boolean isExpired(String expires) {
Date tokenExpiryDate = null;
try {
// The date looks like: 2014-11-13T02:34:59.953729Z
// SimpleDateFormat can't handle the microseconds so take them off
final String tmp = expires.replaceAll("\\.[\\d]+Z", "Z");
tokenExpiryDate = expiryFormat.parse(tmp);
} catch (ParseException e) {
logger.warn("Failure parsing Admin Token expiration date: {}", e.getMessage());
return true;
}
Date current = new Date();
return tokenExpiryDate.getTime() < (current.getTime() + DELTA_TIME_IN_SEC * 1000);
}
final JsonObject passwordHolder = new JsonObject();
passwordHolder.add("user", user);
public void reset() { }
final JsonArray methods = new JsonArray();
methods.add(new JsonPrimitive("password"));
final JsonObject identity = new JsonObject();
identity.add("methods", methods);
identity.add("password", passwordHolder);
boolean scopeDefined = false;
final JsonObject project = new JsonObject();
// If project id is available, it is preferred
if (!projectId.isEmpty()) {
project.addProperty("id", projectId);
scopeDefined = true;
} else if (!projectName.isEmpty()) {
project.add("domain", domain);
project.addProperty("name", projectName);
scopeDefined = true;
}
final JsonObject auth = new JsonObject();
auth.add("identity", identity);
if (scopeDefined) {
final JsonObject scope = new JsonObject();
scope.add("project", project);
auth.add("scope", scope);
}
final JsonObject outer = new JsonObject();
outer.add("auth", auth);
return outer.toString();
}
private StringEntity getUnscopedV3AdminTokenRequest() {
final String body;
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.PASSWORD)) {
body = buildAuth(appConfig.getAdminUser(), appConfig.getAdminPassword(),
appConfig.getAdminProjectId(), appConfig.getAdminProjectName());
} else {
String
msg =
String.format("Admin auth method %s not supported", appConfig.getAdminAuthMethod());
throw new AdminAuthException(msg);
}
try {
return new StringEntity(body);
} catch (UnsupportedEncodingException e) {
throw new AdminAuthException("Invalid V3 authentication request " + e);
}
}
private boolean isExpired(String expires) {
Date tokenExpiryDate = null;
try {
// The date looks like: 2014-11-13T02:34:59.953729Z
// SimpleDateFormat can't handle the microseconds so take them off
final String tmp = expires.replaceAll("\\.[\\d]+Z", "Z");
tokenExpiryDate = expiryFormat.parse(tmp);
} catch (ParseException e) {
logger.warn("Failure parsing Admin Token expiration date: {}", e.getMessage());
return true;
}
Date current = new Date();
return tokenExpiryDate.getTime() < (current.getTime() + DELTA_TIME_IN_SEC * 1000);
}
public void reset() {
}
}