git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/common/authorization-service/2.0@134808 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
7c63514d66
commit
b0917974aa
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<groupId>org.gcube.common</groupId>
|
<groupId>org.gcube.common</groupId>
|
||||||
<artifactId>authorization-service</artifactId>
|
<artifactId>authorization-service</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>2.0.1-SNAPSHOT</version>
|
||||||
<name>authorization service</name>
|
<name>authorization service</name>
|
||||||
|
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
|
@ -62,7 +62,9 @@ public class PolicyManager {
|
||||||
public Policies getPoliciesPerContext(@NotNull @QueryParam("context") String context) {
|
public Policies getPoliciesPerContext(@NotNull @QueryParam("context") String context) {
|
||||||
try{
|
try{
|
||||||
log.info("retrieving polices in context {}", context);
|
log.info("retrieving polices in context {}", context);
|
||||||
return new Policies(tokenPersistence.getPolices(context));
|
Policies policies = new Policies(tokenPersistence.getPolices(context));
|
||||||
|
log.info("returning {} policies from getPoliciesPerContext",policies.getPolicies().size());
|
||||||
|
return policies;
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
log.error("error retrieving policies per context {}", context, e);
|
log.error("error retrieving policies per context {}", context, e);
|
||||||
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
|
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
|
|
@ -20,6 +20,7 @@ import javax.ws.rs.core.Response;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.gcube.common.authorization.library.AuthorizationEntry;
|
import org.gcube.common.authorization.library.AuthorizationEntry;
|
||||||
|
import org.gcube.common.authorization.library.ExternalServiceList;
|
||||||
import org.gcube.common.authorization.library.provider.ContainerInfo;
|
import org.gcube.common.authorization.library.provider.ContainerInfo;
|
||||||
import org.gcube.common.authorization.library.provider.ExternalServiceInfo;
|
import org.gcube.common.authorization.library.provider.ExternalServiceInfo;
|
||||||
import org.gcube.common.authorization.library.provider.ServiceInfo;
|
import org.gcube.common.authorization.library.provider.ServiceInfo;
|
||||||
|
@ -76,6 +77,49 @@ public class TokenManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* retrieves the AuthorzationEntry connected to the specified token
|
||||||
|
*
|
||||||
|
* @param token
|
||||||
|
* @return the authorization entry
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("resolve/{user}")
|
||||||
|
public String getTokenByUserAndContext(@NotNull @PathParam("user") String user, @QueryParam("context") String context ) {
|
||||||
|
|
||||||
|
log.info("resolving token for user {} in context {}",user, context);
|
||||||
|
|
||||||
|
if (context==null){
|
||||||
|
log.error("null context found");
|
||||||
|
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND)
|
||||||
|
.entity("null context found").type(MediaType.TEXT_PLAIN).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = persistence.getExistingToken(user, context, Constants.DEFAULT_TOKEN_QUALIFIER);
|
||||||
|
|
||||||
|
|
||||||
|
if (token == null){
|
||||||
|
log.error("token {} not found ", token);
|
||||||
|
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND)
|
||||||
|
.entity("token for user "+user+" in context "+context+" not found").type(MediaType.TEXT_PLAIN).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: re-add it with common-scope 2.0
|
||||||
|
/*
|
||||||
|
try{
|
||||||
|
ServiceMap map = .instance.getMap(info.getContext());
|
||||||
|
info.setMap(map);
|
||||||
|
}catch(Exception e){
|
||||||
|
log.error("error retrieving map for {}", info.getContext(), e);
|
||||||
|
throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||||
|
.entity("Error retrieving map").type(MediaType.TEXT_PLAIN).build());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return token;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Generates a token for a user (saving the passed roles) if it doesn't exist yet.
|
* Generates a token for a user (saving the passed roles) if it doesn't exist yet.
|
||||||
|
@ -145,21 +189,21 @@ public class TokenManager {
|
||||||
* @param externalServiceInfo
|
* @param externalServiceInfo
|
||||||
* @return the generated token or the token related to the external service (if it was already created)
|
* @return the generated token or the token related to the external service (if it was already created)
|
||||||
*/
|
*/
|
||||||
@Path("external")
|
@Path("external/{serviceId}")
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_XML)
|
@Consumes(MediaType.APPLICATION_XML)
|
||||||
public String generateExternalServiceToken(ExternalServiceInfo externalService, @Context HttpServletRequest req) {
|
public String generateExternalServiceToken(@PathParam("serviceId") String serviceId, @Context HttpServletRequest req) {
|
||||||
try{
|
try{
|
||||||
AuthorizationEntry info = (AuthorizationEntry)req.getAttribute(AuthorizedCallFilter.AUTH_ATTRIBUTE);
|
AuthorizationEntry info = (AuthorizationEntry)req.getAttribute(AuthorizedCallFilter.AUTH_ATTRIBUTE);
|
||||||
log.info("generator called for external service {} in context {} ",externalService.getId(), info.getContext());
|
log.info("generator called for external service {} in context {} ",serviceId, info.getContext());
|
||||||
|
|
||||||
if (externalService.getId().split(":").length>1) throw new Exception("invalid external service id: "+externalService.getId());
|
if (serviceId.split(":").length>1) throw new Exception("invalid external service id: "+serviceId);
|
||||||
|
|
||||||
String token = persistence.getExistingToken(externalService.getId(), info.getContext(), Constants.DEFAULT_TOKEN_QUALIFIER);
|
String token = persistence.getExistingToken(serviceId, info.getContext(), Constants.DEFAULT_TOKEN_QUALIFIER);
|
||||||
|
|
||||||
if (token==null){
|
if (token==null){
|
||||||
token= UUID.randomUUID().toString();
|
token= UUID.randomUUID().toString();
|
||||||
persistence.saveAuthorizationEntry(token, info.getContext(), externalService, Constants.DEFAULT_TOKEN_QUALIFIER, null);
|
persistence.saveAuthorizationEntry(token, info.getContext(), new ExternalServiceInfo(serviceId, info.getClientInfo().getId()), Constants.DEFAULT_TOKEN_QUALIFIER, info.getClientInfo().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
|
@ -170,6 +214,29 @@ public class TokenManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Generates a token for an external service if it doesn't exist yet.
|
||||||
|
*
|
||||||
|
* @param externalServiceInfo
|
||||||
|
* @return the generated token or the token related to the external service (if it was already created)
|
||||||
|
*/
|
||||||
|
@Path("external")
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_XML)
|
||||||
|
public ExternalServiceList getExternalServiceCreated(@Context HttpServletRequest req) {
|
||||||
|
try{
|
||||||
|
AuthorizationEntry info = (AuthorizationEntry)req.getAttribute(AuthorizedCallFilter.AUTH_ATTRIBUTE);
|
||||||
|
log.info("get External Service called in context {} by {} ",info.getContext(), info.getClientInfo().getId());
|
||||||
|
ExternalServiceList toReturn = new ExternalServiceList(persistence.getExistingExternalServices(info.getClientInfo().getId(), info.getContext()));
|
||||||
|
return toReturn;
|
||||||
|
}catch(Exception e){
|
||||||
|
log.error("error generating token ",e);
|
||||||
|
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.entity("Error Generating Token: "+e.getMessage()).type(MediaType.TEXT_PLAIN).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Path("node")
|
@Path("node")
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_XML)
|
@Consumes(MediaType.APPLICATION_XML)
|
||||||
|
|
|
@ -9,6 +9,8 @@ import javax.xml.bind.annotation.XmlAttribute;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import org.gcube.common.authorization.library.ClientType;
|
||||||
|
|
||||||
@XmlRootElement(name="Rule")
|
@XmlRootElement(name="Rule")
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class AuthorizationRule {
|
public class AuthorizationRule {
|
||||||
|
@ -20,16 +22,20 @@ public class AuthorizationRule {
|
||||||
@XmlAttribute(name="requiresToken")
|
@XmlAttribute(name="requiresToken")
|
||||||
private boolean requiresToken = true;
|
private boolean requiresToken = true;
|
||||||
|
|
||||||
|
@XmlAttribute(name="acceptedTokenTypes")
|
||||||
|
private List<ClientType> acceptedTokenType = new ArrayList<ClientType>();
|
||||||
|
|
||||||
@XmlElement(name="Entity")
|
@XmlElement(name="Entity")
|
||||||
private List<AllowedEntity> entities= new ArrayList<AllowedEntity>();
|
private List<AllowedEntity> entities= new ArrayList<AllowedEntity>();
|
||||||
|
|
||||||
protected AuthorizationRule(){}
|
protected AuthorizationRule(){}
|
||||||
|
|
||||||
public AuthorizationRule(String servletPath, List<AllowedEntity> entities, boolean requiresToken) {
|
public AuthorizationRule(String servletPath, List<AllowedEntity> entities, boolean requiresToken, List<ClientType> acceptedTokenType) {
|
||||||
super();
|
super();
|
||||||
this.servletPath = servletPath;
|
this.servletPath = servletPath;
|
||||||
this.entities = entities;
|
this.entities = entities;
|
||||||
this.requiresToken = requiresToken;
|
this.requiresToken = requiresToken;
|
||||||
|
this.acceptedTokenType = acceptedTokenType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServletPath() {
|
public String getServletPath() {
|
||||||
|
@ -45,6 +51,10 @@ public class AuthorizationRule {
|
||||||
return requiresToken;
|
return requiresToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ClientType> getAcceptedTokenType() {
|
||||||
|
return acceptedTokenType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -81,7 +91,7 @@ public class AuthorizationRule {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AuthorizationRule [servletPath=" + servletPath + ", entities="
|
return "AuthorizationRule [servletPath=" + servletPath + ", entities="
|
||||||
+ entities + " requiresToken= "+requiresToken+"]";
|
+ entities + " requiresToken= "+requiresToken+", acceptedTokenType= "+ acceptedTokenType+" ]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package org.gcube.common.authorizationservice.configuration;
|
package org.gcube.common.authorizationservice.configuration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.gcube.common.authorization.library.ClientType;
|
||||||
|
|
||||||
|
|
||||||
public class RuleBuilder {
|
public class RuleBuilder {
|
||||||
|
|
||||||
|
@ -10,6 +13,8 @@ public class RuleBuilder {
|
||||||
|
|
||||||
private List<AllowedEntity> entities = new ArrayList<AllowedEntity>();
|
private List<AllowedEntity> entities = new ArrayList<AllowedEntity>();
|
||||||
|
|
||||||
|
private List<ClientType> acceptedClients = new ArrayList<ClientType>();
|
||||||
|
|
||||||
private boolean requiresToken= true;
|
private boolean requiresToken= true;
|
||||||
|
|
||||||
public RuleBuilder(){}
|
public RuleBuilder(){}
|
||||||
|
@ -24,8 +29,9 @@ public class RuleBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RuleBuilder needsToken(boolean needsToken){
|
public RuleBuilder needsToken(ClientType ... typesAccepted){
|
||||||
this.requiresToken= needsToken;
|
this.requiresToken= true;
|
||||||
|
this.acceptedClients = Arrays.asList(typesAccepted);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +48,6 @@ public class RuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthorizationRule build(){
|
public AuthorizationRule build(){
|
||||||
return new AuthorizationRule(servletPath, entities, requiresToken);
|
return new AuthorizationRule(servletPath, entities, requiresToken, acceptedClients);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -58,16 +58,21 @@ public class AuthorizedCallFilter implements Filter {
|
||||||
String pathInfo = ((HttpServletRequest) request).getPathInfo();
|
String pathInfo = ((HttpServletRequest) request).getPathInfo();
|
||||||
log.info("called path {}", pathInfo);
|
log.info("called path {}", pathInfo);
|
||||||
|
|
||||||
|
if (pathInfo==null || pathInfo.isEmpty()){
|
||||||
|
log.info("call rejected from filters: invalid path info");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (requiresToken(pathInfo) && token==null ){
|
if (requiresToken(pathInfo) && token==null ){
|
||||||
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
log.info("call rejected from filters, call requires caller token");
|
log.info("call rejected from filters, call requires caller token");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String callerIp = ((HttpServletRequest)request).getHeader("x-forwarded-for");
|
String callerIp = ((HttpServletRequest)request).getHeader("x-forwarded-for");
|
||||||
if(callerIp==null)
|
if(callerIp==null)
|
||||||
callerIp=request.getRemoteHost();
|
callerIp=request.getRemoteHost();
|
||||||
log.info("caller ip {}", callerIp);
|
log.info("caller ip {}", callerIp);
|
||||||
|
|
||||||
/*X509Certificate certs[] =
|
/*X509Certificate certs[] =
|
||||||
|
@ -97,32 +102,41 @@ public class AuthorizedCallFilter implements Filter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: review it, something is not working check if is correct that they are in OR
|
||||||
private boolean checkAllowed(String pathInfo, String callerIp, AuthorizationEntry info){
|
private boolean checkAllowed(String pathInfo, String callerIp, AuthorizationEntry info){
|
||||||
AuthorizationConfiguration conf = ConfigurationHolder.getConfiguration();
|
AuthorizationConfiguration conf = ConfigurationHolder.getConfiguration();
|
||||||
List<AuthorizationRule> rules = conf.getAuthorizationRules();
|
List<AuthorizationRule> rules = conf.getAuthorizationRules();
|
||||||
for (AuthorizationRule rule: rules){
|
for (AuthorizationRule rule: rules){
|
||||||
if (!rule.getEntities().isEmpty() && (pathInfo.startsWith(rule.getServletPath()) || pathInfo.equals(rule.getServletPath()))){
|
if (pathInfo.startsWith(rule.getServletPath()) || pathInfo.equals(rule.getServletPath())){
|
||||||
for (AllowedEntity entity : rule.getEntities()){
|
if (!rule.getAcceptedTokenType().isEmpty() && !rule.getAcceptedTokenType().contains(info.getClientInfo().getType())){
|
||||||
switch(entity.getType()){
|
log.info("rejecting the call: callerType {} is not in the allowed types defined {} ", info.getClientInfo().getType(), rule.getAcceptedTokenType());
|
||||||
case IP:
|
return false;
|
||||||
log.trace("checking ip rule : {} -> {}", entity.getValue(), callerIp);
|
}
|
||||||
if(checkIpInRange(callerIp, entity.getValue()))
|
|
||||||
return true;
|
if (!rule.getEntities().isEmpty()){
|
||||||
break;
|
for (AllowedEntity entity : rule.getEntities()){
|
||||||
case USER:
|
switch(entity.getType()){
|
||||||
log.trace("checking user rule : {} -> {}", entity.getValue(), info.getClientInfo().getId());
|
case IP:
|
||||||
if (entity.getValue().equals(info.getClientInfo().getId()))
|
log.trace("checking ip rule : {} -> {}", entity.getValue(), callerIp);
|
||||||
return entity.getValue().equals(info.getClientInfo().getId());
|
if(checkIpInRange(callerIp, entity.getValue()))
|
||||||
break;
|
return true;
|
||||||
case ROLE:
|
break;
|
||||||
log.trace("checking role rule : {} -> {}", entity.getValue(), info.getClientInfo().getRoles());
|
case USER:
|
||||||
if (info.getClientInfo().getRoles().contains(entity.getValue()))
|
log.trace("checking user rule : {} -> {}", entity.getValue(), info.getClientInfo().getId());
|
||||||
return true;
|
if (entity.getValue().equals(info.getClientInfo().getId()))
|
||||||
break;
|
return true;
|
||||||
}
|
break;
|
||||||
|
case ROLE:
|
||||||
|
log.trace("checking role rule : {} -> {}", entity.getValue(), info.getClientInfo().getRoles());
|
||||||
|
if (info.getClientInfo().getRoles().contains(entity.getValue()))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//IF a servlet path matches the caller is not allowed to that servlet (the call should be rejected)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
//IF a servlet path matches the caller is not allowed to that servlet (the call should be rejected)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
package org.gcube.common.authorizationservice.persistence;
|
package org.gcube.common.authorizationservice.persistence;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
@ -46,6 +47,10 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
@Inject
|
@Inject
|
||||||
EntityManagerFactory emFactory;
|
EntityManagerFactory emFactory;
|
||||||
|
|
||||||
|
ReentrantLock lock = new ReentrantLock(true);
|
||||||
|
|
||||||
|
HashMap<String, AuthorizationId> synchMap = new HashMap<String, AuthorizationId>();
|
||||||
|
|
||||||
//ONLY FOR TEST PURPOSE
|
//ONLY FOR TEST PURPOSE
|
||||||
public void setEntitymanagerFactory(EntityManagerFactory emf){
|
public void setEntitymanagerFactory(EntityManagerFactory emf){
|
||||||
this.emFactory = emf;
|
this.emFactory = emf;
|
||||||
|
@ -60,11 +65,7 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
query.setParameter("token", token);
|
query.setParameter("token", token);
|
||||||
AuthorizationEntity authEntity;
|
AuthorizationEntity authEntity;
|
||||||
try{
|
try{
|
||||||
em.getTransaction().begin();
|
|
||||||
authEntity = query.getSingleResult();
|
authEntity = query.getSingleResult();
|
||||||
authEntity.setLastTimeUsed(Calendar.getInstance());
|
|
||||||
em.merge(authEntity);
|
|
||||||
em.getTransaction().commit();
|
|
||||||
}catch (NoResultException e){
|
}catch (NoResultException e){
|
||||||
log.warn("no result found for token {}",token);
|
log.warn("no result found for token {}",token);
|
||||||
return null;
|
return null;
|
||||||
|
@ -115,19 +116,36 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
else if (info instanceof ExternalServiceInfo) authEntity = new ExternalServiceAuthorizationEntity(token, context, tokenQualifier, (ExternalServiceInfo) info, generatedBy);
|
else if (info instanceof ExternalServiceInfo) authEntity = new ExternalServiceAuthorizationEntity(token, context, tokenQualifier, (ExternalServiceInfo) info, generatedBy);
|
||||||
else authEntity = new NodeAuthorizationEntity(token, context, tokenQualifier, (ContainerInfo) info, generatedBy);
|
else authEntity = new NodeAuthorizationEntity(token, context, tokenQualifier, (ContainerInfo) info, generatedBy);
|
||||||
|
|
||||||
EntityManager em = emFactory.createEntityManager();
|
AuthorizationId authId = new AuthorizationId(context, info.getId(), tokenQualifier);
|
||||||
|
lock.lock();
|
||||||
try{
|
try{
|
||||||
em.getTransaction().begin();
|
if (synchMap.containsKey(authId.toString()))
|
||||||
em.persist(authEntity);
|
authId = synchMap.get(authId.toString());
|
||||||
em.getTransaction().commit();
|
else synchMap.put(authId.toString(), authId);
|
||||||
}catch(RuntimeException e){
|
}finally{
|
||||||
log.error("error saving authorization Entry", e);
|
lock.unlock();
|
||||||
em.getTransaction().rollback();
|
|
||||||
throw e;
|
|
||||||
} finally{
|
|
||||||
em.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (authId) {
|
||||||
|
EntityManager em = emFactory.createEntityManager();
|
||||||
|
EntityTransaction tx = em.getTransaction();
|
||||||
|
try{
|
||||||
|
tx.begin();
|
||||||
|
AuthorizationEntity ae = em.find(AuthorizationEntity.class, authId);
|
||||||
|
log.trace("AuthorizationEntity {} found, saving it", (ae==null)?"not":"");
|
||||||
|
if (ae==null)
|
||||||
|
em.persist(authEntity);
|
||||||
|
tx.commit();
|
||||||
|
}catch(RuntimeException e){
|
||||||
|
log.error("error saving authorization Entry", e);
|
||||||
|
if (tx.isActive())
|
||||||
|
tx.rollback();
|
||||||
|
throw e;
|
||||||
|
} finally{
|
||||||
|
em.close();
|
||||||
|
synchMap.remove(authId.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +165,9 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
|
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
|
log.error("error storing policy",e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}finally{
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +185,9 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
else log.warn("policy with id {} not found", policyId);
|
else log.warn("policy with id {} not found", policyId);
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
log.error("error removing policy with id {}", policyId);
|
log.error("error removing policy with id {}", policyId,e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}finally{
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,14 +197,16 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
List<Policy> policiesToReturn = new ArrayList<Policy>();
|
List<Policy> policiesToReturn = new ArrayList<Policy>();
|
||||||
EntityManager em = emFactory.createEntityManager();
|
EntityManager em = emFactory.createEntityManager();
|
||||||
try{
|
try{
|
||||||
TypedQuery<PolicyEntity> query = em.createNamedQuery("Policy.all", PolicyEntity.class);
|
TypedQuery<PolicyEntity> query = em.createNamedQuery("Policy.allPolicies", PolicyEntity.class);
|
||||||
query.setParameter("context", context);
|
query.setParameter("context", context);
|
||||||
for (PolicyEntity pEntity: query.getResultList()){
|
log.info("query to get all policies in context {} , {} ", query.getParameterValue("context"), query.toString());
|
||||||
|
List<PolicyEntity> entities = query.getResultList();
|
||||||
|
for (PolicyEntity pEntity: entities ){
|
||||||
Policy policy;
|
Policy policy;
|
||||||
if (pEntity.getPolicyType().equals(EntityConstants.SERVICE_POLICY)){
|
if (pEntity.getPolicyType().equals(EntityConstants.SERVICE_POLICY)){
|
||||||
policy = new Service2ServicePolicy(context, pEntity.getServiceAccess(), ((ServicePolicyEntity) pEntity).getClientAccess(), pEntity.getAction());
|
policy = new Service2ServicePolicy(pEntity.getContext(), pEntity.getServiceAccess(), ((ServicePolicyEntity) pEntity).getClientAccess(), pEntity.getAction());
|
||||||
}else
|
}else
|
||||||
policy = new User2ServicePolicy(context, pEntity.getServiceAccess(), ((UserPolicyEntity) pEntity).getUser(), pEntity.getAction());
|
policy = new User2ServicePolicy(pEntity.getContext(), pEntity.getServiceAccess(), ((UserPolicyEntity) pEntity).getUser(), pEntity.getAction());
|
||||||
policy.setId(pEntity.getId());
|
policy.setId(pEntity.getId());
|
||||||
policy.setCreationTime(pEntity.getCreationTime());
|
policy.setCreationTime(pEntity.getCreationTime());
|
||||||
policy.setLastUpdateTime(pEntity.getLastUpdateTime());
|
policy.setLastUpdateTime(pEntity.getLastUpdateTime());
|
||||||
|
@ -190,6 +215,7 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
}finally{
|
}finally{
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
log.info("policies to return are {} ",policiesToReturn.size());
|
||||||
return policiesToReturn;
|
return policiesToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +280,12 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
return policies;
|
return policies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* return a map with key qualifier and value the corresponding token
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getExistingApiKeys(String clientId, String context) {
|
public Map<String, String> getExistingApiKeys(String clientId, String context) {
|
||||||
EntityManager em = emFactory.createEntityManager();
|
EntityManager em = emFactory.createEntityManager();
|
||||||
|
@ -272,6 +304,32 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* return a map with key the external service id and value the corresponding token
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getExistingExternalServices(String generatorId, String context) {
|
||||||
|
EntityManager em = emFactory.createEntityManager();
|
||||||
|
|
||||||
|
try{
|
||||||
|
TypedQuery<ExternalServiceAuthorizationEntity> queryS = em.createNamedQuery("ExternalService.getByGenerator", ExternalServiceAuthorizationEntity.class);
|
||||||
|
queryS.setParameter("context", context);
|
||||||
|
queryS.setParameter("generatorId", generatorId);
|
||||||
|
List<ExternalServiceAuthorizationEntity> externals = queryS.getResultList();
|
||||||
|
Map<String, String> externalServiceMapping = new HashMap<String, String>();
|
||||||
|
for (ExternalServiceAuthorizationEntity external: externals)
|
||||||
|
externalServiceMapping.put(external.getClientId(), external.getToken());
|
||||||
|
return externalServiceMapping;
|
||||||
|
}finally{
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -291,32 +349,4 @@ public class RelationDBPersistence implements TokenPersistence{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* @Override
|
|
||||||
public Key getSymmetricKey(String token) {
|
|
||||||
EntityManager em = emFactory.createEntityManager();
|
|
||||||
try{
|
|
||||||
//retrieve entity for token
|
|
||||||
TypedQuery<AuthorizationEntity> query = em.createNamedQuery("Authz.get", AuthorizationEntity.class);
|
|
||||||
query.setParameter("token", token);
|
|
||||||
AuthorizationEntity authEntity;
|
|
||||||
try{
|
|
||||||
authEntity = query.getSingleResult();
|
|
||||||
}catch (NoResultException e){
|
|
||||||
log.warn("no result found for token {}",token);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return authEntity.getApiSymmetricKey();
|
|
||||||
|
|
||||||
}catch(Throwable t){
|
|
||||||
log.error("error retrieving key fro token {}",token, t);
|
|
||||||
return null;
|
|
||||||
}finally{
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,46 @@ public class AuthorizationId {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AuthorizationId [context=" + context
|
return context+clientId+qualifier;
|
||||||
+ ", clientId=" + clientId + " qualifier ="+qualifier+"]";
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result
|
||||||
|
+ ((clientId == null) ? 0 : clientId.hashCode());
|
||||||
|
result = prime * result + ((context == null) ? 0 : context.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((qualifier == null) ? 0 : qualifier.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
AuthorizationId other = (AuthorizationId) obj;
|
||||||
|
if (clientId == null) {
|
||||||
|
if (other.clientId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!clientId.equals(other.clientId))
|
||||||
|
return false;
|
||||||
|
if (context == null) {
|
||||||
|
if (other.context != null)
|
||||||
|
return false;
|
||||||
|
} else if (!context.equals(other.context))
|
||||||
|
return false;
|
||||||
|
if (qualifier == null) {
|
||||||
|
if (other.qualifier != null)
|
||||||
|
return false;
|
||||||
|
} else if (!qualifier.equals(other.qualifier))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@ import org.gcube.common.authorization.library.provider.ExternalServiceInfo;
|
||||||
@DiscriminatorValue(EntityConstants.EXTERNAL_SERVICE_AUTHORIZATION)
|
@DiscriminatorValue(EntityConstants.EXTERNAL_SERVICE_AUTHORIZATION)
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name="ExternalService.get", query="SELECT info FROM ExternalServiceAuthorizationEntity info WHERE "
|
@NamedQuery(name="ExternalService.get", query="SELECT info FROM ExternalServiceAuthorizationEntity info WHERE "
|
||||||
+ " info.token=:token AND info.id.context=:context AND info.id.clientId=:clientId")
|
+ " info.token=:token AND info.id.context=:context AND info.id.clientId=:clientId"),
|
||||||
|
@NamedQuery(name="ExternalService.getByGenerator", query="SELECT info FROM ExternalServiceAuthorizationEntity info WHERE "
|
||||||
|
+ " info.id.context=:context AND info.internalInfo.generatedBy=:generatorId")
|
||||||
})
|
})
|
||||||
public class ExternalServiceAuthorizationEntity extends AuthorizationEntity{
|
public class ExternalServiceAuthorizationEntity extends AuthorizationEntity{
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ public class ExternalServiceAuthorizationEntity extends AuthorizationEntity{
|
||||||
|
|
||||||
public ExternalServiceAuthorizationEntity(String token, String context, String qualifier,
|
public ExternalServiceAuthorizationEntity(String token, String context, String qualifier,
|
||||||
ExternalServiceInfo externalServiceInfo, String generatedBy) {
|
ExternalServiceInfo externalServiceInfo, String generatedBy) {
|
||||||
super(token, context, externalServiceInfo, qualifier, EntityConstants.SERVICE_AUTHORIZATION, generatedBy);
|
super(token, context, externalServiceInfo, qualifier, EntityConstants.EXTERNAL_SERVICE_AUTHORIZATION, generatedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.NamedQueries;
|
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
|
@ -25,10 +24,7 @@ import org.gcube.common.authorization.library.policies.ServiceAccess;
|
||||||
@Inheritance
|
@Inheritance
|
||||||
@DiscriminatorColumn(name="PolicyType")
|
@DiscriminatorColumn(name="PolicyType")
|
||||||
@Table(name="Policies")
|
@Table(name="Policies")
|
||||||
@NamedQueries({
|
@NamedQuery(name="Policy.allPolicies", query="SELECT policy FROM PolicyEntity policy WHERE policy.context = :context")
|
||||||
@NamedQuery(name="Policy.all", query="SELECT policy FROM PolicyEntity policy WHERE "
|
|
||||||
+ " policy.context=:context")
|
|
||||||
})
|
|
||||||
public abstract class PolicyEntity {
|
public abstract class PolicyEntity {
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
|
@ -127,4 +123,15 @@ public abstract class PolicyEntity {
|
||||||
|
|
||||||
public abstract boolean isRewritable();
|
public abstract boolean isRewritable();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PolicyEntity [id=" + id + ", context=" + context
|
||||||
|
+ ", policyType=" + policyType + ", serviceAccess="
|
||||||
|
+ serviceAccess + ", accessServiceClass=" + accessServiceClass
|
||||||
|
+ ", accessServiceName=" + accessServiceName
|
||||||
|
+ ", accessServiceIdentifier=" + accessServiceIdentifier
|
||||||
|
+ ", action=" + action + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class ServicePolicyEntity extends PolicyEntity {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ServicePolicyEntity [clientAccessEntity=" + clientAccessEntity
|
return "ServicePolicyEntity [clientAccessEntity=" + clientAccessEntity
|
||||||
+ ", excludes=" + excludes + "]";
|
+ ", toString()=" + super.toString() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,8 @@ public class UserPolicyEntity extends PolicyEntity{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "UserPolicyEntity [userClient=" + userClient + ", type=" + type
|
return "UserPolicyEntity [identifier=" + identifier + ", toString()="
|
||||||
+ ", excludes=" + excludes + ", identifier=" + identifier + "]";
|
+ super.toString() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,4 +30,7 @@ public interface TokenPersistence {
|
||||||
|
|
||||||
List<Policy> getPolicesByTypeAndClientId(String context, PolicyType type,
|
List<Policy> getPolicesByTypeAndClientId(String context, PolicyType type,
|
||||||
String clientId);
|
String clientId);
|
||||||
|
|
||||||
|
Map<String, String> getExistingExternalServices(String generatorId,
|
||||||
|
String context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<class>org.gcube.common.authorizationservice.persistence.entities.UserPolicyEntity</class>
|
<class>org.gcube.common.authorizationservice.persistence.entities.UserPolicyEntity</class>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="javax.persistence.jdbc.url"
|
<property name="javax.persistence.jdbc.url"
|
||||||
value="jdbc:postgresql://postgres1-d-d4s.d4science.org/authorization" />
|
value="jdbc:postgresql://auth-db-dev-d4s.d4science.org/authorization" />
|
||||||
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
|
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
|
||||||
<property name="javax.persistence.jdbc.user" value="authorization" />
|
<property name="javax.persistence.jdbc.user" value="authorization" />
|
||||||
<property name="javax.persistence.jdbc.password" value="auth_dem0l33t" />
|
<property name="javax.persistence.jdbc.password" value="auth_dem0l33t" />
|
||||||
|
|
|
@ -1,20 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<Configuration>
|
<Configuration>
|
||||||
<Rule path="/token/user" requiresToken="false">
|
<Rule path="/token/user" requiresToken="false"/>
|
||||||
<Entity type="IP" value="146.48.80.0" />
|
<Rule path="/apikey" requiresToken="true" acceptedTokenTypes="USER"/>
|
||||||
<Entity type="IP" value="146.48.81.0" />
|
<Rule path="/policyManager" requiresToken="true"/>
|
||||||
<Entity type="IP" value="146.48.82.0" />
|
<Rule path="/token/external" requiresToken="true" acceptedTokenTypes="USER" />
|
||||||
<Entity type="IP" value="146.48.83.0" />
|
<Rule path="/token/node" requiresToken="false" />
|
||||||
<Entity type="IP" value="146.48.84.0" />
|
<Rule path="/token/service" requiresToken="true" acceptedTokenTypes="CONTAINER"/>
|
||||||
<Entity type="IP" value="146.48.85.0" />
|
|
||||||
<Entity type="IP" value="146.48.122.0" />
|
|
||||||
<Entity type="IP" value="146.48.123.0" />
|
|
||||||
|
|
||||||
</Rule>
|
|
||||||
<Rule path="/apikey" requiresToken="true" />
|
|
||||||
<Rule path="/policyManager" requiresToken="true" />
|
|
||||||
<Rule path="/token/external" requiresToken="true" />
|
|
||||||
<Rule path="/token/node" requiresToken="false" />
|
|
||||||
<Rule path="/token/service" requiresToken="true" />
|
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import javax.ws.rs.client.Entity;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
import org.gcube.common.authorization.library.provider.ContainerInfo;
|
import org.gcube.common.authorization.library.provider.ContainerInfo;
|
||||||
|
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||||
import org.gcube.common.authorization.library.provider.ServiceIdentifier;
|
import org.gcube.common.authorization.library.provider.ServiceIdentifier;
|
||||||
import org.gcube.common.authorization.library.provider.ServiceInfo;
|
import org.gcube.common.authorization.library.provider.ServiceInfo;
|
||||||
import org.gcube.common.authorization.library.provider.UserInfo;
|
import org.gcube.common.authorization.library.provider.UserInfo;
|
||||||
|
@ -34,6 +35,8 @@ public class GenerateTest extends JerseyTest{
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateTokenForUser() {
|
public void generateTokenForUser() {
|
||||||
|
|
||||||
|
@ -67,6 +70,7 @@ public class GenerateTest extends JerseyTest{
|
||||||
Assert.assertNotNull(token);
|
Assert.assertNotNull(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(expected=Exception.class)
|
@Test(expected=Exception.class)
|
||||||
public void generateTokenForNodeERROR() {
|
public void generateTokenForNodeERROR() {
|
||||||
target("token").path("node")
|
target("token").path("node")
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.io.StringWriter;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
|
|
||||||
|
import org.gcube.common.authorization.library.ClientType;
|
||||||
import org.gcube.common.authorizationservice.configuration.AllowedEntity;
|
import org.gcube.common.authorizationservice.configuration.AllowedEntity;
|
||||||
import org.gcube.common.authorizationservice.configuration.AllowedEntity.EntityType;
|
import org.gcube.common.authorizationservice.configuration.AllowedEntity.EntityType;
|
||||||
import org.gcube.common.authorizationservice.configuration.AuthorizationConfiguration;
|
import org.gcube.common.authorizationservice.configuration.AuthorizationConfiguration;
|
||||||
|
@ -28,7 +29,7 @@ public class Binder {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void binder() throws Exception{
|
public void binder() throws Exception{
|
||||||
AuthorizationRule firtRule = new RuleBuilder().path("/*").entity(new AllowedEntity(EntityType.IP, "192.168.0.1")).entity(new AllowedEntity(EntityType.IP, "192.168.0.2")).build();
|
AuthorizationRule firtRule = new RuleBuilder().path("/*").entity(new AllowedEntity(EntityType.IP, "192.168.0.1")).entity(new AllowedEntity(EntityType.IP, "192.168.0.2")).needsToken(ClientType.USER, ClientType.CONTAINER).build();
|
||||||
AuthorizationRule secondRule = new RuleBuilder().path("/newPath").entity(new AllowedEntity(EntityType.ROLE, "ContextManager")).entity(new AllowedEntity(EntityType.IP, "192.168.0.3")).build();
|
AuthorizationRule secondRule = new RuleBuilder().path("/newPath").entity(new AllowedEntity(EntityType.ROLE, "ContextManager")).entity(new AllowedEntity(EntityType.IP, "192.168.0.3")).build();
|
||||||
AuthorizationRule thirdRule = new RuleBuilder().path("/anotherPath").entity(new AllowedEntity(EntityType.USER, "user")).build();
|
AuthorizationRule thirdRule = new RuleBuilder().path("/anotherPath").entity(new AllowedEntity(EntityType.USER, "user")).build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue