package org.springframework.security.oauth.provider.expression;
import java.util.List;
import java.util.Set;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.MethodExecutor;
import org.springframework.expression.MethodResolver;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth.provider.OAuthAuthenticationDetails;
/**
* @author Ryan Heaton
* @author Dave Syer
*/
public class OAuthMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
@Override
public StandardEvaluationContext createEvaluationContextInternal(Authentication auth, MethodInvocation mi) {
StandardEvaluationContext ec = super.createEvaluationContextInternal(auth, mi);
ec.addMethodResolver(new OAuthMethodResolver());
return ec;
}
public static boolean consumerHasAnyRole(SecurityExpressionRoot root, String... roles) {
Authentication authentication = root.getAuthentication();
if (authentication.getDetails() instanceof OAuthAuthenticationDetails) {
OAuthAuthenticationDetails details = (OAuthAuthenticationDetails) authentication.getDetails();
List<GrantedAuthority> consumerAuthorities = details.getConsumerDetails().getAuthorities();
if (consumerAuthorities != null) {
Set<String> roleSet = AuthorityUtils.authorityListToSet(consumerAuthorities);
for (String role : roles) {
if (roleSet.contains(role)) {
return true;
}
}
}
}
return false;
}
public static boolean isOAuthConsumerAuth(SecurityExpressionRoot root) {
Authentication authentication = root.getAuthentication();
if (authentication.getDetails() instanceof OAuthAuthenticationDetails) {
return true;
}
return false;
}
private static class OAuthMethodResolver implements MethodResolver {
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
List<TypeDescriptor> argumentTypes) throws AccessException {
if (targetObject instanceof SecurityExpressionRoot) {
if ("oauthConsumerHasRole".equals(name) || "oauthConsumerHasAnyRole".equals(name)) {
return new OAuthClientRoleExecutor();
} else if ("denyOAuthConsumer".equals(name)) {
return new DenyOAuthClientRoleExecutor();
}
}
return null;
}
}
private static class OAuthClientRoleExecutor implements MethodExecutor {
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
String[] roles = new String[arguments.length];
for (int i = 0; i < arguments.length; i++) {
roles[i] = String.valueOf(arguments[i]);
}
return new TypedValue(consumerHasAnyRole((SecurityExpressionRoot) target, roles));
}
}
private static class DenyOAuthClientRoleExecutor implements MethodExecutor {
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
return new TypedValue(!isOAuthConsumerAuth((SecurityExpressionRoot) target));
}
}
}