|
|
@ -18,7 +18,6 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
package org.wso2.carbon.webapp.authenticator.framework.authenticator;
|
|
|
|
package org.wso2.carbon.webapp.authenticator.framework.authenticator;
|
|
|
|
|
|
|
|
|
|
|
|
import org.apache.catalina.connector.Request;
|
|
|
|
|
|
|
|
import org.apache.catalina.connector.Response;
|
|
|
|
import org.apache.catalina.connector.Response;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
@ -27,7 +26,6 @@ import org.apache.tomcat.util.buf.MessageBytes;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationFrameworkUtil;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationFrameworkUtil;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.Constants;
|
|
|
|
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException;
|
|
|
|
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException;
|
|
|
@ -43,53 +41,51 @@ public class OAuthAuthenticator implements WebappAuthenticator {
|
|
|
|
|
|
|
|
|
|
|
|
private static final String OAUTH_AUTHENTICATOR = "OAuth";
|
|
|
|
private static final String OAUTH_AUTHENTICATOR = "OAuth";
|
|
|
|
private static final String REGEX_BEARER_PATTERN = "[B|b]earer\\s";
|
|
|
|
private static final String REGEX_BEARER_PATTERN = "[B|b]earer\\s";
|
|
|
|
private static final Pattern PATTERN = Pattern.compile(REGEX_BEARER_PATTERN);
|
|
|
|
private static final Pattern PATTERN = Pattern.compile("[B|b]earer\\s");
|
|
|
|
private static final String BEARER_TOKEN_TYPE = "bearer";
|
|
|
|
private static final String BEARER_TOKEN_TYPE = "bearer";
|
|
|
|
private static final String RESOURCE_KEY = "resource";
|
|
|
|
private static final String RESOURCE_KEY = "resource";
|
|
|
|
|
|
|
|
|
|
|
|
private Properties properties;
|
|
|
|
private Properties properties;
|
|
|
|
private OAuth2TokenValidator tokenValidator;
|
|
|
|
private OAuth2TokenValidator tokenValidator;
|
|
|
|
|
|
|
|
|
|
|
|
private static final Log log = LogFactory.getLog(OAuthAuthenticator.class);
|
|
|
|
private static final Log log = LogFactory.getLog(OAuthAuthenticator.class);
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void init() {
|
|
|
|
public void init() {
|
|
|
|
if (properties == null) {
|
|
|
|
if (this.properties == null) {
|
|
|
|
throw new IllegalArgumentException("Required properties needed to initialize OAuthAuthenticator are " +
|
|
|
|
throw new IllegalArgumentException("Required properties needed to initialize OAuthAuthenticator " +
|
|
|
|
"not provided");
|
|
|
|
"are not provided");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String url = properties.getProperty("TokenValidationEndpointUrl");
|
|
|
|
|
|
|
|
if (url == null || url.isEmpty()) {
|
|
|
|
String url = this.properties.getProperty("TokenValidationEndpointUrl");
|
|
|
|
|
|
|
|
if ((url == null) || (url.isEmpty())) {
|
|
|
|
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
|
|
|
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String adminUsername = properties.getProperty("Username");
|
|
|
|
String adminUsername = this.properties.getProperty("Username");
|
|
|
|
if (adminUsername == null) {
|
|
|
|
if (adminUsername == null) {
|
|
|
|
throw new IllegalArgumentException("Username to connect to the OAuth token validation endpoint is " +
|
|
|
|
throw new IllegalArgumentException("Username to connect to the OAuth token validation endpoint " +
|
|
|
|
"not provided");
|
|
|
|
"is not provided");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String adminPassword = properties.getProperty("Password");
|
|
|
|
|
|
|
|
|
|
|
|
String adminPassword = this.properties.getProperty("Password");
|
|
|
|
if (adminPassword == null) {
|
|
|
|
if (adminPassword == null) {
|
|
|
|
throw new IllegalArgumentException("Password to connect to the OAuth token validation endpoint is " +
|
|
|
|
throw new IllegalArgumentException("Password to connect to the OAuth token validation endpoint " +
|
|
|
|
"not provided");
|
|
|
|
"is not provided");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean isRemote = Boolean.parseBoolean(properties.getProperty("IsRemote"));
|
|
|
|
|
|
|
|
|
|
|
|
boolean isRemote = Boolean.parseBoolean(this.properties.getProperty("IsRemote"));
|
|
|
|
|
|
|
|
|
|
|
|
Properties validatorProperties = new Properties();
|
|
|
|
Properties validatorProperties = new Properties();
|
|
|
|
validatorProperties.setProperty("MaxTotalConnections", properties.getProperty("MaxTotalConnections"));
|
|
|
|
validatorProperties.setProperty("MaxTotalConnections", this.properties.getProperty("MaxTotalConnections"));
|
|
|
|
validatorProperties.setProperty("MaxConnectionsPerHost", properties.getProperty("MaxConnectionsPerHost"));
|
|
|
|
validatorProperties.setProperty("MaxConnectionsPerHost", this.properties.getProperty("MaxConnectionsPerHost"));
|
|
|
|
this.tokenValidator =
|
|
|
|
this.tokenValidator =
|
|
|
|
OAuthValidatorFactory.getNewValidator(url, adminUsername, adminPassword, isRemote, validatorProperties);
|
|
|
|
OAuthValidatorFactory.getValidator(url, adminUsername, adminPassword, isRemote, validatorProperties);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean canHandle(org.apache.catalina.connector.Request request) {
|
|
|
|
public boolean canHandle(Request request) {
|
|
|
|
MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("Authorization");
|
|
|
|
MessageBytes authorization =
|
|
|
|
|
|
|
|
request.getCoyoteRequest().getMimeHeaders().getValue(Constants.HTTPHeaders.HEADER_HTTP_AUTHORIZATION);
|
|
|
|
|
|
|
|
String tokenValue;
|
|
|
|
|
|
|
|
if (authorization != null) {
|
|
|
|
if (authorization != null) {
|
|
|
|
authorization.toBytes();
|
|
|
|
authorization.toBytes();
|
|
|
|
ByteChunk authBC = authorization.getByteChunk();
|
|
|
|
ByteChunk authBC = authorization.getByteChunk();
|
|
|
|
tokenValue = authBC.toString();
|
|
|
|
String tokenValue = authBC.toString();
|
|
|
|
Matcher matcher = PATTERN.matcher(tokenValue);
|
|
|
|
Matcher matcher = PATTERN.matcher(tokenValue);
|
|
|
|
if (matcher.find()) {
|
|
|
|
if (matcher.find()) {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
@ -98,49 +94,46 @@ public class OAuthAuthenticator implements WebappAuthenticator {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public AuthenticationInfo authenticate(org.apache.catalina.connector.Request request, Response response) {
|
|
|
|
public AuthenticationInfo authenticate(Request request, Response response) {
|
|
|
|
|
|
|
|
String requestUri = request.getRequestURI();
|
|
|
|
String requestUri = request.getRequestURI();
|
|
|
|
String requestMethod = request.getMethod();
|
|
|
|
String requestMethod = request.getMethod();
|
|
|
|
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
|
|
|
|
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
|
|
|
|
if (requestUri == null || "".equals(requestUri)) {
|
|
|
|
if ((requestUri == null) || ("".equals(requestUri))) {
|
|
|
|
authenticationInfo.setStatus(Status.CONTINUE);
|
|
|
|
authenticationInfo.setStatus(WebappAuthenticator.Status.CONTINUE);
|
|
|
|
return authenticationInfo;
|
|
|
|
return authenticationInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StringTokenizer tokenizer = new StringTokenizer(requestUri, "/");
|
|
|
|
StringTokenizer tokenizer = new StringTokenizer(requestUri, "/");
|
|
|
|
String context = tokenizer.nextToken();
|
|
|
|
String context = tokenizer.nextToken();
|
|
|
|
if (context == null || "".equals(context)) {
|
|
|
|
if ((context == null) || ("".equals(context))) {
|
|
|
|
authenticationInfo.setStatus(Status.CONTINUE);
|
|
|
|
authenticationInfo.setStatus(WebappAuthenticator.Status.CONTINUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String apiVersion = tokenizer.nextToken();
|
|
|
|
String apiVersion = tokenizer.nextToken();
|
|
|
|
//String authLevel = authenticator.getResourceAuthenticationScheme(context, apiVersion, requestUri, requestMethod);
|
|
|
|
|
|
|
|
String authLevel = "any";
|
|
|
|
String authLevel = "any";
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if (Constants.NO_MATCHING_AUTH_SCHEME.equals(authLevel)) {
|
|
|
|
if ("noMatchedAuthScheme".equals(authLevel)) {
|
|
|
|
AuthenticationFrameworkUtil.handleNoMatchAuthScheme(request, response, requestMethod, apiVersion,
|
|
|
|
AuthenticationFrameworkUtil.handleNoMatchAuthScheme(
|
|
|
|
context);
|
|
|
|
request, response, requestMethod, apiVersion, context);
|
|
|
|
authenticationInfo.setStatus(Status.CONTINUE);
|
|
|
|
|
|
|
|
|
|
|
|
authenticationInfo.setStatus(WebappAuthenticator.Status.CONTINUE);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
String bearerToken = this.getBearerToken(request);
|
|
|
|
String bearerToken = getBearerToken(request);
|
|
|
|
//Set the resource context param. This will be used in scope validation.
|
|
|
|
|
|
|
|
String resource = requestUri + ":" + requestMethod;
|
|
|
|
String resource = requestUri + ":" + requestMethod;
|
|
|
|
|
|
|
|
|
|
|
|
OAuthValidationResponse oAuthValidationResponse = tokenValidator.validateToken(bearerToken, resource);
|
|
|
|
OAuthValidationResponse oAuthValidationResponse =
|
|
|
|
|
|
|
|
this.tokenValidator.validateToken(bearerToken, resource);
|
|
|
|
|
|
|
|
|
|
|
|
if (oAuthValidationResponse.isValid()) {
|
|
|
|
if (oAuthValidationResponse.isValid()) {
|
|
|
|
String username = oAuthValidationResponse.getUserName();
|
|
|
|
String username = oAuthValidationResponse.getUserName();
|
|
|
|
String tenantDomain = oAuthValidationResponse.getTenantDomain();
|
|
|
|
String tenantDomain = oAuthValidationResponse.getTenantDomain();
|
|
|
|
//Remove the userstore domain from username
|
|
|
|
|
|
|
|
/*if (username.contains("/")) {
|
|
|
|
|
|
|
|
username = username.substring(username.indexOf('/') + 1);
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
authenticationInfo.setUsername(username);
|
|
|
|
authenticationInfo.setUsername(username);
|
|
|
|
authenticationInfo.setTenantDomain(tenantDomain);
|
|
|
|
authenticationInfo.setTenantDomain(tenantDomain);
|
|
|
|
authenticationInfo.setTenantId(Utils.getTenantIdOFUser(username + "@" + tenantDomain));
|
|
|
|
authenticationInfo.setTenantId(Utils.getTenantIdOFUser(username + "@" + tenantDomain));
|
|
|
|
if (oAuthValidationResponse.isValid()) {
|
|
|
|
if (oAuthValidationResponse.isValid())
|
|
|
|
authenticationInfo.setStatus(Status.CONTINUE);
|
|
|
|
authenticationInfo.setStatus(WebappAuthenticator.Status.CONTINUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
authenticationInfo.setMessage(oAuthValidationResponse.getErrorMsg());
|
|
|
|
authenticationInfo.setMessage(oAuthValidationResponse.getErrorMsg());
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -153,33 +146,28 @@ public class OAuthAuthenticator implements WebappAuthenticator {
|
|
|
|
return authenticationInfo;
|
|
|
|
return authenticationInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public String getName() {
|
|
|
|
public String getName() {
|
|
|
|
return OAuthAuthenticator.OAUTH_AUTHENTICATOR;
|
|
|
|
return "OAuth";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public String getProperty(String name) {
|
|
|
|
public String getProperty(String name) {
|
|
|
|
if (properties == null) {
|
|
|
|
if (this.properties == null) {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return properties.getProperty(name);
|
|
|
|
return this.properties.getProperty(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Properties getProperties() {
|
|
|
|
public Properties getProperties() {
|
|
|
|
return properties;
|
|
|
|
return this.properties;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void setProperties(Properties properties) {
|
|
|
|
public void setProperties(Properties properties) {
|
|
|
|
this.properties = properties;
|
|
|
|
this.properties = properties;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String getBearerToken(Request request) {
|
|
|
|
private String getBearerToken(org.apache.catalina.connector.Request request) {
|
|
|
|
MessageBytes authorization =
|
|
|
|
MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("Authorization");
|
|
|
|
request.getCoyoteRequest().getMimeHeaders().
|
|
|
|
|
|
|
|
getValue(Constants.HTTPHeaders.HEADER_HTTP_AUTHORIZATION);
|
|
|
|
|
|
|
|
String tokenValue = null;
|
|
|
|
String tokenValue = null;
|
|
|
|
if (authorization != null) {
|
|
|
|
if (authorization != null) {
|
|
|
|
authorization.toBytes();
|
|
|
|
authorization.toBytes();
|
|
|
|