org.apache.cxf.interceptor.security.SecureAnnotationsInterceptor Maven / Gradle / Ivy
/**
* 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.cxf.interceptor.security;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.ClassHelper;
public class SecureAnnotationsInterceptor extends SimpleAuthorizingInterceptor {
private static final Logger LOG = LogUtils.getL7dLogger(SecureAnnotationsInterceptor.class);
private static final String DEFAULT_ANNOTATION_CLASS_NAME = "javax.annotation.security.RolesAllowed";
private static final Set SKIP_METHODS;
static {
SKIP_METHODS = new HashSet();
SKIP_METHODS.addAll(Arrays.asList(
new String[] {"wait", "notify", "notifyAll",
"equals", "toString", "hashCode"}));
}
private String annotationClassName = DEFAULT_ANNOTATION_CLASS_NAME;
public void setAnnotationClassName(String name) {
try {
ClassLoaderUtils.loadClass(name, SecureAnnotationsInterceptor.class);
annotationClassName = name;
} catch (Throwable ex) {
ex.printStackTrace();
throw new IllegalArgumentException("Annotation class " + name + " is not available");
}
}
public void setSecuredObject(Object object) {
Class cls = ClassHelper.getRealClass(object);
Map rolesMap = new HashMap();
findRoles(cls, rolesMap);
if (rolesMap.isEmpty()) {
LOG.warning("The roles map is empty, the service object is not protected");
} else if (LOG.isLoggable(Level.FINE)) {
for (Map.Entry entry : rolesMap.entrySet()) {
LOG.fine("Method: " + entry.getKey() + ", roles: " + entry.getValue());
}
}
super.setMethodRolesMap(rolesMap);
}
protected void findRoles(Class cls, Map rolesMap) {
if (cls == null || cls == Object.class) {
return;
}
String classRolesAllowed = getRoles(cls.getAnnotations(), annotationClassName);
for (Method m : cls.getMethods()) {
if (SKIP_METHODS.contains(m.getName())) {
continue;
}
String methodRolesAllowed = getRoles(m.getAnnotations(), annotationClassName);
String theRoles = methodRolesAllowed != null ? methodRolesAllowed : classRolesAllowed;
if (theRoles != null) {
rolesMap.put(m.getName(), theRoles);
rolesMap.put(createMethodSig(m), theRoles);
}
}
if (!rolesMap.isEmpty()) {
return;
}
findRoles(cls.getSuperclass(), rolesMap);
if (!rolesMap.isEmpty()) {
return;
}
for (Class interfaceCls : cls.getInterfaces()) {
findRoles(interfaceCls, rolesMap);
}
}
private String getRoles(Annotation[] anns, String annName) {
for (Annotation ann : anns) {
if (ann.annotationType().getName().equals(annName)) {
try {
Method valueMethod = ann.annotationType().getMethod("value", new Class[]{});
String[] roles = (String[])valueMethod.invoke(ann, new Object[]{});
StringBuilder sb = new StringBuilder();
for (int i = 0; i < roles.length; i++) {
sb.append(roles[i]);
if (i + 1 < roles.length) {
sb.append(" ");
}
}
return sb.toString();
} catch (Exception ex) {
// ignore
}
break;
}
}
return null;
}
}