/*
* oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2014, Gluu
*/
package org.xdi.oxauth.service.uma.authorization;
import org.slf4j.Logger;
import org.xdi.model.custom.script.conf.CustomScriptConfiguration;
import org.xdi.oxauth.model.common.AuthorizationGrant;
import org.xdi.oxauth.model.common.UnmodifiableAuthorizationGrant;
import org.xdi.oxauth.model.common.uma.UmaRPT;
import org.xdi.oxauth.model.uma.ClaimTokenList;
import org.xdi.oxauth.model.uma.persistence.ResourceSetPermission;
import org.xdi.oxauth.model.uma.persistence.ScopeDescription;
import org.xdi.oxauth.service.AttributeService;
import org.xdi.oxauth.service.external.ExternalUmaAuthorizationPolicyService;
import org.xdi.oxauth.service.uma.ScopeService;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Yuriy Zabrovarnyy
* @version 0.9, 22/02/2013
*/
@Stateless
@Named("umaAuthorizationService")
public class AuthorizationService {
@Inject
private Logger log;
@Inject
private ScopeService umaScopeService;
@Inject
private ExternalUmaAuthorizationPolicyService externalUmaAuthorizationPolicyService;
@Inject
private AttributeService attributeService;
public boolean allowToAddPermission(AuthorizationGrant grant, UmaRPT rpt, ResourceSetPermission permission, HttpServletRequest httpRequest, ClaimTokenList claims) {
log.trace("Check policies for permission, id: '{}'", permission.getDn());
List<ScopeDescription> scopes = umaScopeService.getScopesByDns(permission.getScopeDns());
return allowToAddPermission(grant, rpt, scopes, permission, httpRequest, claims);
}
public boolean allowToAddPermissionForGat(AuthorizationGrant grant, UmaRPT rpt, List<String> scopes, HttpServletRequest httpRequest, ClaimTokenList claims) {
List<ScopeDescription> scopesByUrls = umaScopeService.getScopesByUrls(scopes);
return allowToAddPermission(grant, rpt, scopesByUrls, new ResourceSetPermission(), httpRequest, claims);
}
public boolean allowToAddPermission(AuthorizationGrant grant, UmaRPT rpt, List<ScopeDescription> scopes,
ResourceSetPermission permission, HttpServletRequest httpRequest, ClaimTokenList claims) {
log.trace("Check policies for scopes: '{}'", scopes);
Set<String> authorizationPolicies = getAuthorizationPolicies(scopes);
if (authorizationPolicies == null || authorizationPolicies.isEmpty()) {
log.trace("No policies protection, allowed to grant permission.");
return true;
} else {
final UnmodifiableAuthorizationGrant unmodifiableAuthorizationGrant = new UnmodifiableAuthorizationGrant(grant);
final AuthorizationContext context = new AuthorizationContext(attributeService, rpt, permission, unmodifiableAuthorizationGrant, httpRequest, claims);
for (String authorizationPolicy : authorizationPolicies) {
// if at least one policy returns false then whole result is false
if (!applyPolicy(authorizationPolicy, context)) {
log.trace("Reject access. Policy dn: '{}'", authorizationPolicy);
return false;
}
}
log.trace("All policies are ok, grant access.");
return true;
}
}
private Set<String> getAuthorizationPolicies(List<ScopeDescription> scopes) {
HashSet<String> result = new HashSet<String>();
for (ScopeDescription scope : scopes) {
List<String> authorizationPolicies = scope.getAuthorizationPolicies();
if (authorizationPolicies != null) {
result.addAll(authorizationPolicies);
}
}
return result;
}
private boolean applyPolicy(String authorizationPolicyDn, AuthorizationContext authorizationContext) {
log.trace("Apply policy dn: '{}' ...", authorizationPolicyDn);
final CustomScriptConfiguration customScriptConfiguration = externalUmaAuthorizationPolicyService.getAuthorizationPolicyByDn(authorizationPolicyDn);
if (customScriptConfiguration != null) {
final boolean result = externalUmaAuthorizationPolicyService.executeExternalAuthorizeMethod(customScriptConfiguration, authorizationContext);
log.trace("Policy '{}' result: {}", authorizationPolicyDn, result);
// if false check whether "need_info" objects are set, if yes then throw WebApplicationException directly here
if (!result) {
if (authorizationContext.getNeedInfoAuthenticationContext() != null || authorizationContext.getNeedInfoRequestingPartyClaims() != null) {
final String jsonEntity = NeedInfoResponseBuilder.entityForResponse(
authorizationContext.getNeedInfoAuthenticationContext(), authorizationContext.getNeedInfoRequestingPartyClaims());
throwForbiddenException(jsonEntity);
}
}
return result;
} else {
log.error("Unable to load custom script dn: '{}'", authorizationPolicyDn);
}
return false;
}
private static void throwForbiddenException(String entity) {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN)
.entity(entity).build());
}
}