use of org.apache.cxf.interceptor.security.AuthenticationException in project carbon-apimgt by wso2.
the class BasicAuthenticationInterceptor method handleMessage.
/**
* This method handles the incoming message by checking if an anonymous api is being called or invalid
* authorization headers are present in the request. If not, authenticate the request.
*
* @param inMessage cxf Message
*/
@Override
@MethodStats
public void handleMessage(Message inMessage) {
// by-passes the interceptor if user calls an anonymous api
if (RestApiUtil.checkIfAnonymousAPI(inMessage)) {
return;
}
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
inMessage.put(RestApiConstants.TENANT_DOMAIN, tenantDomain);
// Extract and check if "Authorization: Basic" is present in the request. If not, by-passes the interceptor.
// If yes, set the request_authentication_scheme property in the message as basic_auth and execute the basic
// authentication flow.
AuthorizationPolicy policy = inMessage.get(AuthorizationPolicy.class);
if (policy != null) {
inMessage.put(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME, RestApiConstants.BASIC_AUTHENTICATION);
// Extract user credentials from the auth header and validate.
String username = StringUtils.trim(policy.getUserName());
String password = StringUtils.trim(policy.getPassword());
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
String errorMessage = StringUtils.isEmpty(username) ? "username cannot be null/empty." : "password cannot be null/empty.";
log.error("Basic Authentication failed: " + errorMessage);
throw new AuthenticationException("Unauthenticated request");
} else if (!authenticate(inMessage, username, password)) {
throw new AuthenticationException("Unauthenticated request");
}
log.debug("User logged into web app using Basic Authentication");
}
}
use of org.apache.cxf.interceptor.security.AuthenticationException in project meecrowave by apache.
the class OAuth2Configurer method preCompute.
// TODO: still some missing configuration for jwt etc to add/wire from OAuth2Options
@PostConstruct
private void preCompute() {
configuration = builder.getExtension(OAuth2Options.class);
final Function<JwtClaims, JwtClaims> customizeClaims = configuration.isUseJwtFormatForAccessTokens() ? claims -> {
if (claims.getIssuer() == null) {
claims.setIssuer(configuration.getJwtIssuer());
}
return claims;
} : identity();
AbstractOAuthDataProvider provider;
switch(configuration.getProvider().toLowerCase(ENGLISH)) {
case "jpa":
{
if (!configuration.isAuthorizationCodeSupport()) {
// else use code impl
final JPAOAuthDataProvider jpaProvider = new JPAOAuthDataProvider() {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
jpaProvider.setEntityManagerFactory(JPAAdapter.createEntityManagerFactory(configuration));
provider = jpaProvider;
break;
}
}
case "jpa-code":
{
final JPACodeDataProvider jpaProvider = new JPACodeDataProvider() {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
jpaProvider.setEntityManagerFactory(JPAAdapter.createEntityManagerFactory(configuration));
provider = jpaProvider;
break;
}
case "jcache":
if (!configuration.isAuthorizationCodeSupport()) {
// else use code impl
jCacheConfigurer.doSetup(configuration);
try {
provider = new JCacheOAuthDataProvider(configuration.getJcacheConfigUri(), bus, configuration.isJcacheStoreJwtKeyOnly()) {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
} catch (final Exception e) {
throw new IllegalStateException(e);
}
break;
}
case "jcache-code":
jCacheConfigurer.doSetup(configuration);
try {
provider = new JCacheCodeDataProvider(configuration, bus) {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
} catch (final Exception e) {
throw new IllegalStateException(e);
}
break;
case "encrypted":
if (!configuration.isAuthorizationCodeSupport()) {
// else use code impl
provider = new DefaultEncryptingOAuthDataProvider(new SecretKeySpec(configuration.getEncryptedKey().getBytes(StandardCharsets.UTF_8), configuration.getEncryptedAlgo())) {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
break;
}
case "encrypted-code":
provider = new DefaultEncryptingCodeDataProvider(new SecretKeySpec(configuration.getEncryptedKey().getBytes(StandardCharsets.UTF_8), configuration.getEncryptedAlgo())) {
@Override
protected JwtClaims createJwtAccessToken(final ServerAccessToken at) {
return customizeClaims.apply(super.createJwtAccessToken(at));
}
@Override
protected ServerAccessToken createNewAccessToken(final Client client, final UserSubject userSub) {
final ServerAccessToken token = super.createNewAccessToken(client, userSub);
forwardClaims(client, userSub, token);
return token;
}
};
break;
default:
throw new IllegalArgumentException("Unsupported oauth2 provider: " + configuration.getProvider());
}
final RefreshTokenGrantHandler refreshTokenGrantHandler = new RefreshTokenGrantHandler() {
@Override
public ServerAccessToken createAccessToken(final Client client, final MultivaluedMap<String, String> params) throws OAuthServiceException {
final ServerAccessToken accessToken = super.createAccessToken(client, params);
forwardClaims(client, accessToken.getSubject(), accessToken);
return accessToken;
}
};
refreshTokenGrantHandler.setDataProvider(provider);
refreshTokenGrantHandler.setUseAllClientScopes(configuration.isUseAllClientScopes());
refreshTokenGrantHandler.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
final ResourceOwnerLoginHandler loginHandler = configuration.isJaas() ? new JAASResourceOwnerLoginHandler() {
@Override
public UserSubject createSubject(final Client client, final String name, final String password) {
final UserSubject subject = super.createSubject(client, name, password);
forwardRolesAsClaims(subject);
return subject;
}
} : (client, name, password) -> {
try {
request.login(name, password);
try {
final Principal pcp = request.getUserPrincipal();
return doCreateUserSubject(pcp);
} finally {
request.logout();
}
} catch (final ServletException e) {
throw new AuthenticationException(e.getMessage());
}
};
final List<AccessTokenGrantHandler> handlers = new ArrayList<>();
handlers.add(refreshTokenGrantHandler);
handlers.add(new ClientCredentialsGrantHandler() {
@Override
protected ServerAccessToken doCreateAccessToken(final Client client, final UserSubject subject, final String requestedGrant, final List<String> requestedScopes, final List<String> audiences) {
final ServerAccessToken serverAccessToken = super.doCreateAccessToken(client, subject, requestedGrant, requestedScopes, audiences);
forwardClaims(client, subject, serverAccessToken);
return serverAccessToken;
}
});
handlers.add(new ResourceOwnerGrantHandler() {
{
setLoginHandler(loginHandler);
}
@Override
protected ServerAccessToken doCreateAccessToken(final Client client, final UserSubject subject, final String requestedGrant, final List<String> requestedScopes, final List<String> audiences) {
final ServerAccessToken serverAccessToken = super.doCreateAccessToken(client, subject, requestedGrant, requestedScopes, audiences);
forwardClaims(client, subject, serverAccessToken);
return serverAccessToken;
}
});
handlers.add(new AuthorizationCodeGrantHandler() {
@Override
public ServerAccessToken createAccessToken(final Client client, final MultivaluedMap<String, String> params) throws OAuthServiceException {
if (configuration.isUseS256CodeChallenge()) {
setCodeVerifierTransformer(new DigestCodeVerifier());
}
return super.createAccessToken(client, params);
}
@Override
protected ServerAccessToken doCreateAccessToken(final Client client, final UserSubject subject, final String requestedGrant, final List<String> requestedScopes, final List<String> audiences) {
final ServerAccessToken serverAccessToken = super.doCreateAccessToken(client, subject, requestedGrant, requestedScopes, audiences);
forwardClaims(client, subject, serverAccessToken);
return serverAccessToken;
}
});
handlers.add(new JwtBearerGrantHandler() {
@Override
protected ServerAccessToken doCreateAccessToken(final Client client, final UserSubject subject, final String requestedGrant, final List<String> requestedScopes, final List<String> audiences) {
final ServerAccessToken serverAccessToken = super.doCreateAccessToken(client, subject, requestedGrant, requestedScopes, audiences);
forwardClaims(client, subject, serverAccessToken);
return serverAccessToken;
}
});
provider.setUseJwtFormatForAccessTokens(configuration.isUseJwtFormatForAccessTokens());
provider.setAccessTokenLifetime(configuration.getAccessTokenLifetime());
provider.setRefreshTokenLifetime(configuration.getRefreshTokenLifetime());
provider.setRecycleRefreshTokens(configuration.isRecycleRefreshTokens());
provider.setSupportPreauthorizedTokens(configuration.isSupportPreauthorizedTokens());
ofNullable(configuration.getRequiredScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setRequiredScopes);
ofNullable(configuration.getDefaultScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setDefaultScopes);
ofNullable(configuration.getInvisibleToClientScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setInvisibleToClientScopes);
ofNullable(configuration.getJwtAccessTokenClaimMap()).map(s -> new Properties() {
{
try {
load(new StringReader(s));
} catch (IOException e) {
throw new IllegalArgumentException("Bad claim map configuration, use properties syntax");
}
}
}).ifPresent(m -> provider.setJwtAccessTokenClaimMap(new HashMap<>(Map.class.cast(m))));
final OAuthDataProvider dataProvider;
if (configuration.isRefreshToken()) {
dataProvider = new RefreshTokenEnabledProvider(provider);
if (provider.getInvisibleToClientScopes() == null) {
provider.setInvisibleToClientScopes(new ArrayList<>());
}
provider.getInvisibleToClientScopes().add(OAuthConstants.REFRESH_TOKEN_SCOPE);
} else {
dataProvider = provider;
}
handlers.stream().filter(AbstractGrantHandler.class::isInstance).forEach(h -> {
final AbstractGrantHandler handler = AbstractGrantHandler.class.cast(h);
handler.setDataProvider(dataProvider);
handler.setCanSupportPublicClients(configuration.isCanSupportPublicClients());
handler.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
});
abstractTokenServiceConsumer = s -> {
// this is used @RequestScoped so ensure it is not slow for no reason
s.setCanSupportPublicClients(configuration.isCanSupportPublicClients());
s.setBlockUnsecureRequests(configuration.isBlockUnsecureRequests());
s.setWriteCustomErrors(configuration.isWriteCustomErrors());
s.setWriteOptionalParameters(configuration.isWriteOptionalParameters());
s.setDataProvider(dataProvider);
};
tokenServiceConsumer = s -> {
// this is used @RequestScoped so ensure it is not slow for no reason
abstractTokenServiceConsumer.accept(s);
s.setGrantHandlers(handlers);
};
final List<String> noConsentScopes = ofNullable(configuration.getScopesRequiringNoConsent()).map(s -> asList(s.split(","))).orElse(null);
// we prefix them oauth2.cxf. but otherwise it is the plain cxf config
securityProperties = ofNullable(builder.getProperties()).map(Properties::stringPropertyNames).orElse(emptySet()).stream().filter(s -> s.startsWith("oauth2.cxf.rs.security.")).collect(toMap(s -> s.substring("oauth2.cxf.".length()), s -> builder.getProperties().getProperty(s)));
final JoseSessionTokenProvider sessionAuthenticityTokenProvider = new JoseSessionTokenProvider() {
@Override
public String createSessionToken(final MessageContext mc, final MultivaluedMap<String, String> params, final UserSubject subject, final OAuthRedirectionState secData) {
// CXF-8368
secData.setClientCodeChallenge(params.getFirst(OAuthConstants.AUTHORIZATION_CODE_CHALLENGE));
return super.createSessionToken(mc, params, subject, secData);
}
};
sessionAuthenticityTokenProvider.setMaxDefaultSessionInterval(configuration.getMaxDefaultSessionInterval());
// TODO: other configs
redirectionBasedGrantServiceConsumer = s -> {
s.setDataProvider(dataProvider);
s.setBlockUnsecureRequests(configuration.isBlockUnsecureRequests());
s.setWriteOptionalParameters(configuration.isWriteOptionalParameters());
s.setUseAllClientScopes(configuration.isUseAllClientScopes());
s.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
s.setUseRegisteredRedirectUriIfPossible(configuration.isUseRegisteredRedirectUriIfPossible());
s.setMaxDefaultSessionInterval(configuration.getMaxDefaultSessionInterval());
s.setMatchRedirectUriWithApplicationUri(configuration.isMatchRedirectUriWithApplicationUri());
s.setScopesRequiringNoConsent(noConsentScopes);
s.setSessionAuthenticityTokenProvider(sessionAuthenticityTokenProvider);
s.setCanSupportPublicClients(configuration.isCanSupportPublicClients());
};
}
use of org.apache.cxf.interceptor.security.AuthenticationException in project carbon-apimgt by wso2.
the class GlobalThrowableMapper method toResponse.
@Override
public Response toResponse(Throwable e) {
if (e instanceof ClientErrorException) {
log.error("Client error", e);
return ((ClientErrorException) e).getResponse();
}
if (e instanceof NotFoundException) {
log.error("Resource not found", e);
return ((NotFoundException) e).getResponse();
}
if (e instanceof PreconditionFailedException) {
log.error("Precondition failed", e);
return ((PreconditionFailedException) e).getResponse();
}
if (e instanceof BadRequestException) {
log.error("Bad request", e);
return ((BadRequestException) e).getResponse();
}
if (e instanceof ConstraintViolationException) {
log.error("Constraint violation", e);
return ((ConstraintViolationException) e).getResponse();
}
if (e instanceof ForbiddenException) {
log.error("Resource forbidden", e);
return ((ForbiddenException) e).getResponse();
}
if (e instanceof ConflictException) {
log.error("Conflict", e);
return ((ConflictException) e).getResponse();
}
if (e instanceof MethodNotAllowedException) {
log.error("Method not allowed", e);
return ((MethodNotAllowedException) e).getResponse();
}
if (e instanceof InternalServerErrorException) {
String errorMessage = "The server encountered an internal error : " + e.getMessage();
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON_TYPE).entity(e500).build();
}
if (e instanceof JsonParseException) {
String errorMessage = "Malformed request body.";
log.error(errorMessage, e);
// noinspection ThrowableResultOfMethodCallIgnored
return RestApiUtil.buildBadRequestException(errorMessage).getResponse();
}
if (e instanceof JsonMappingException) {
if (e instanceof UnrecognizedPropertyException) {
UnrecognizedPropertyException unrecognizedPropertyException = (UnrecognizedPropertyException) e;
String unrecognizedProperty = unrecognizedPropertyException.getPropertyName();
String errorMessage = "Unrecognized property '" + unrecognizedProperty + "'";
log.error(errorMessage, e);
// noinspection ThrowableResultOfMethodCallIgnored
return RestApiUtil.buildBadRequestException(errorMessage).getResponse();
} else {
String errorMessage = "One or more request body parameters contain disallowed values.";
log.error(errorMessage, e);
// noinspection ThrowableResultOfMethodCallIgnored
return RestApiUtil.buildBadRequestException(errorMessage).getResponse();
}
}
if (e instanceof AuthenticationException) {
ErrorDTO errorDetail = new ErrorDTO();
errorDetail.setCode((long) 401);
errorDetail.setMoreInfo("");
errorDetail.setMessage("");
errorDetail.setDescription(e.getMessage());
return Response.status(Response.Status.UNAUTHORIZED).type(MediaType.APPLICATION_JSON_TYPE).entity(errorDetail).build();
}
// This occurs when received an empty body in an occasion where the body is mandatory
if (e instanceof EOFException) {
String errorMessage = "Request payload cannot be empty.";
log.error(errorMessage, e);
// noinspection ThrowableResultOfMethodCallIgnored
return RestApiUtil.buildBadRequestException(errorMessage).getResponse();
}
if (e instanceof APIManagementException) {
ErrorHandler selectedErrorHandler = null;
List<Throwable> throwableList = ExceptionUtils.getThrowableList(e);
for (Throwable t : throwableList) {
if (t instanceof APIManagementException) {
APIManagementException apimException = (APIManagementException) t;
ErrorHandler errorHandler = apimException.getErrorHandler();
if (errorHandler != null) {
if (selectedErrorHandler == null) {
selectedErrorHandler = errorHandler;
} else {
selectedErrorHandler = errorHandler.getHttpStatusCode() < selectedErrorHandler.getHttpStatusCode() && errorHandler.getHttpStatusCode() > 0 ? errorHandler : selectedErrorHandler;
}
}
}
}
if (selectedErrorHandler != null) {
// logs the error as the error may be not logged by the origin
if (selectedErrorHandler.printStackTrace()) {
log.error("A defined exception has been captured and mapped to an HTTP response " + "by the global exception mapper ", e);
} else {
// Not to log the stack trace due to error code was mark as not print stacktrace.
log.error(e.getMessage());
if (log.isDebugEnabled()) {
log.debug("A defined exception has been captured and mapped to an HTTP response " + "by the global exception mapper ", e);
}
}
ErrorDTO errorDTO = RestApiUtil.getErrorDTO(selectedErrorHandler);
return Response.status(Response.Status.fromStatusCode(selectedErrorHandler.getHttpStatusCode())).type(MediaType.APPLICATION_JSON_TYPE).entity(errorDTO).build();
}
}
// unknown exception log and return
log.error("An unknown exception has been captured by the global exception mapper.", e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON_TYPE).entity(e500).build();
}
use of org.apache.cxf.interceptor.security.AuthenticationException in project carbon-apimgt by wso2.
the class OAuthAuthenticationInterceptor method handleMessage.
@Override
@MethodStats
public void handleMessage(Message inMessage) {
// by-passes the interceptor if user calls an anonymous api
if (RestApiUtil.checkIfAnonymousAPI(inMessage)) {
return;
}
HashMap<String, Object> authContext = JWTAuthenticationUtils.addToJWTAuthenticationContext(inMessage);
RestAPIAuthenticator authenticator = RestAPIAuthenticationManager.getAuthenticator(authContext);
if (authenticator != null) {
try {
String authenticationType = authenticator.getAuthenticationType();
inMessage.put(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME, authenticator.getAuthenticationType());
String basePath = (String) inMessage.get(RestApiConstants.BASE_PATH);
String version = (String) inMessage.get(RestApiConstants.API_VERSION);
authContext.put(RestApiConstants.URI_TEMPLATES, RestApiUtil.getURITemplatesForBasePath(basePath + version));
authContext.put(RestApiConstants.ORG_ID, RestApiUtil.resolveOrganization(inMessage));
if (authenticator.authenticate(authContext)) {
inMessage = JWTAuthenticationUtils.addToMessageContext(inMessage, authContext);
if (logger.isDebugEnabled()) {
logger.debug("Request has been Authenticated , authentication type : " + authenticationType);
}
} else {
logger.error("Failed to Authenticate , authentication type : " + authenticationType);
throw new AuthenticationException("Unauthenticated request");
}
} catch (APIManagementException e) {
logger.error("Authentication Failure " + e.getMessage());
return;
}
}
// Following logic will be moved to separate class in near future
if (authenticator == null) {
String accessToken = RestApiUtil.extractOAuthAccessTokenFromMessage(inMessage, RestApiConstants.REGEX_BEARER_PATTERN, RestApiConstants.AUTH_HEADER_NAME);
// add masked token to the Message
inMessage.put(RestApiConstants.MASKED_TOKEN, APIUtil.getMaskedToken(accessToken));
if (accessToken == null) {
return;
}
if (accessToken.contains(RestApiConstants.DOT)) {
inMessage.put(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME, RestApiConstants.JWT_AUTHENTICATION);
} else {
inMessage.put(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME, RestApiConstants.OPAQUE_AUTHENTICATION);
}
try {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Authenticating request with : " + inMessage.get(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME)) + "Authentication");
}
AbstractOAuthAuthenticator abstractOAuthAuthenticator = authenticatorMap.get(inMessage.get(RestApiConstants.REQUEST_AUTHENTICATION_SCHEME));
logger.debug("Selected Authenticator for the token validation " + abstractOAuthAuthenticator);
if (abstractOAuthAuthenticator.authenticate(inMessage)) {
if (logger.isDebugEnabled()) {
logger.debug("User logged into Web app using OAuth Authentication");
}
} else {
throw new AuthenticationException("Unauthenticated request");
}
} catch (APIManagementException e) {
logger.error("Error while authenticating incoming request to API Manager REST API", e);
}
}
}
use of org.apache.cxf.interceptor.security.AuthenticationException in project cxf by apache.
the class HttpAuthenticationFaultHandler method handleFault.
@Override
public void handleFault(Message message) {
Exception ex = message.getContent(Exception.class);
if (ex instanceof AuthenticationException) {
HttpServletResponse resp = (HttpServletResponse) message.getExchange().getInMessage().get(AbstractHTTPDestination.HTTP_RESPONSE);
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
resp.setHeader("WWW-Authenticate", authenticationType + " realm=\"" + realm + "\"");
resp.setContentType("text/plain");
try {
resp.getOutputStream().write(ex.getMessage().getBytes());
resp.getOutputStream().flush();
// avoid return soap fault
message.getInterceptorChain().setFaultObserver(null);
message.getInterceptorChain().abort();
} catch (IOException e) {
// TODO
}
}
}
Aggregations