blob: 03da0e8558910e86dc0134e676cd90921c8c2cbe [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.usergrid.rest.security.shiro.filters;
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.exception.OAuthSystemException;
import org.apache.amber.oauth2.common.message.types.ParameterStyle;
import org.apache.amber.oauth2.common.utils.OAuthUtils;
import org.apache.amber.oauth2.rs.request.OAuthAccessResourceRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.subject.Subject;
import org.apache.usergrid.management.ApplicationInfo;
import org.apache.usergrid.management.OrganizationInfo;
import org.apache.usergrid.management.UserInfo;
import org.apache.usergrid.management.exceptions.ManagementException;
import org.apache.usergrid.security.AuthPrincipalInfo;
import org.apache.usergrid.security.AuthPrincipalType;
import org.apache.usergrid.security.shiro.PrincipalCredentialsToken;
import org.apache.usergrid.security.shiro.utils.SubjectUtils;
import org.apache.usergrid.security.tokens.TokenInfo;
import org.apache.usergrid.security.tokens.exceptions.BadTokenException;
import org.apache.usergrid.security.tokens.exceptions.ExpiredTokenException;
import org.apache.usergrid.security.tokens.exceptions.InvalidTokenException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import static org.apache.usergrid.rest.exceptions.AuthErrorInfo.*;
import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
@Provider
@PreMatching
public class OAuth2AccessTokenSecurityFilter extends SecurityFilter implements ContainerRequestFilter {
public static final String REALM = "Usergrid Authentication";
private static final Logger logger = LoggerFactory.getLogger( OAuth2AccessTokenSecurityFilter.class );
public OAuth2AccessTokenSecurityFilter() {
logger.info( "OAuth2AccessTokenSecurityFilter is installed" );
}
@Context
protected HttpServletRequest httpServletRequest;
@Override
public void filter(ContainerRequestContext request) throws IOException {
if (logger.isTraceEnabled()) {
logger.trace("Filtering: {}", request.getUriInfo().getBaseUri());
}
try {
try {
String accessToken = httpServletRequest.getParameter( "access_token" );
if (StringUtils.isEmpty( accessToken )) {
// Make the OAuth Request out of this request
OAuthAccessResourceRequest oauthRequest =
new OAuthAccessResourceRequest( httpServletRequest, ParameterStyle.HEADER );
// Get the access token
accessToken = oauthRequest.getAccessToken();
}
if (StringUtils.isEmpty( accessToken )) {
return;
}
AuthPrincipalInfo principal = null;
try {
// will update access time in principal if statements below, don't do it here
TokenInfo tokenInfo = tokens.getTokenInfo( accessToken, false );
principal = tokenInfo.getPrincipal();
} catch (BadTokenException e1) {
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
} catch (ExpiredTokenException ete) {
throw mappableSecurityException( EXPIRED_ACCESS_TOKEN_ERROR );
} catch (InvalidTokenException ite) {
throw mappableSecurityException( INVALID_AUTH_ERROR );
} catch (IndexOutOfBoundsException ioobe) {
// token is just some rubbish string
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug( "Unable to verify OAuth token: " + accessToken, e );
} else {
logger.warn( "Unable to verify OAuth token" );
}
throw mappableSecurityException( UNVERIFIED_OAUTH_ERROR );
}
if (principal == null) {
return;
}
PrincipalCredentialsToken token = null;
if (AuthPrincipalType.ADMIN_USER.equals( principal.getType() )) {
UserInfo user = null;
try {
user = management.getAdminUserInfoFromAccessToken( accessToken );
} catch (ManagementException e) {
throw mappableSecurityException( e, BAD_ACCESS_TOKEN_ERROR );
} catch (Exception e) {
logger.error( "failed to get admin user info from access token", e );
}
if (user == null) {
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
}
token = PrincipalCredentialsToken.getFromAdminUserInfoAndAccessToken(
user, accessToken, emf.getManagementAppId() );
} else if (AuthPrincipalType.APPLICATION_USER.equals( principal.getType() )) {
UserInfo user = null;
try {
user = management.getAppUserFromAccessToken( accessToken );
} catch (ManagementException e) {
throw mappableSecurityException( e, BAD_ACCESS_TOKEN_ERROR );
} catch (Exception e) {
logger.error( "failed to get app user from access token", e );
}
if (user == null) {
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
}
token = PrincipalCredentialsToken.getFromAppUserInfoAndAccessToken( user, accessToken );
} else if (AuthPrincipalType.ORGANIZATION.equals( principal.getType() )) {
OrganizationInfo organization = null;
try {
organization = management.getOrganizationInfoFromAccessToken( accessToken );
} catch (ManagementException e) {
throw mappableSecurityException( e, BAD_ACCESS_TOKEN_ERROR );
} catch (Exception e) {
logger.error( "failed to get organization info from access token", e );
}
if (organization == null) {
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
}
token = PrincipalCredentialsToken
.getFromOrganizationInfoAndAccessToken( organization, accessToken );
} else if (AuthPrincipalType.APPLICATION.equals( principal.getType() )) {
ApplicationInfo application = null;
try {
application = management.getApplicationInfoFromAccessToken( accessToken );
} catch (ManagementException e) {
throw mappableSecurityException( e, BAD_ACCESS_TOKEN_ERROR );
} catch (Exception e) {
logger.error( "failed to get application info from access token", e );
}
if (application == null) {
throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
}
token = PrincipalCredentialsToken.getFromApplicationInfoAndAccessToken( application, accessToken );
}
Subject subject = SubjectUtils.getSubject();
subject.login( token );
} catch (OAuthProblemException e) {
// Check if the error code has been set
String errorCode = e.getError();
if (OAuthUtils.isEmpty( errorCode )) {
return;
}
throw mappableSecurityException( errorCode, e.getMessage(), null );
}
} catch (OAuthSystemException ose) {
throw mappableSecurityException( ose, null );
}
}
}