package de.cinovo.cloudconductor.server.security; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.core.HttpHeaders; import org.apache.cxf.message.Message; import org.apache.cxf.security.SecurityContext; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import de.cinovo.cloudconductor.server.dao.IAgentAuthTokenDAO; import de.cinovo.cloudconductor.server.dao.IAgentDAO; import de.cinovo.cloudconductor.server.model.EAgent; import de.cinovo.cloudconductor.server.model.EAgentAuthToken; import de.taimos.springcxfdaemon.providers.AuthorizationProvider; /** * Copyright 2016 Cinovo AG<br> * <br> * * @author ablehm * */ public class TokenAuthProvider extends AuthorizationProvider { private static final String TOKEN = "TOKEN"; private static final Boolean TOKEN_AUTH = Boolean.valueOf(System.getProperty("cloudconductor.restauthmandatory", "true")); @Autowired private IAgentAuthTokenDAO dToken; @Autowired private IAgentDAO dAgent; @Override protected boolean isAuthorizationMandatory() { return TokenAuthProvider.TOKEN_AUTH; } @Override protected SecurityContext handleAuthHeader(ContainerRequestContext requestContext, Message msg, String type, String auth1) { SecurityContext result = this.noTokenNeededCheck(); if (result != null) { return result; } return this.doTokenAuth(type, auth1); } @Override protected SecurityContext handleOther(ContainerRequestContext requestContext, Message msg, HttpHeaders head) { return this.noTokenNeededCheck(); } /** * This Method allows login for tokens following the Convention for a Header: "Authentication: TOKEN 'Token'_'AgentName'" */ private SecurityContext doTokenAuth(String type, String auth1) { if (type.equals(TokenAuthProvider.TOKEN)) { // Convention: String has the following Form: "Authentication: TOKEN <Token>_<AgentName>" // auth1 is already reduced to: "<Token>_<AgentName>" String token = auth1.split("_")[0]; String agentName = auth1.split("_")[1]; EAgentAuthToken authToken = this.dToken.findByToken(token); if (authToken == null) { this.handleUnknownToken(token, agentName); return null; } if ((authToken.getRevoked() != null)) { this.handleAgent(agentName, authToken); return null; } EAgent agent = this.handleAgent(agentName, authToken); return AuthorizationProvider.createSC(agent.getName()); } return null; } private void handleUnknownToken(String token, String agentName) { EAgentAuthToken brokenToken = new EAgentAuthToken(); brokenToken.setToken(token); brokenToken.setCreationDate(DateTime.now().getMillis()); brokenToken.setRevoked(DateTime.now().getMillis()); brokenToken.setRevokeComment("Unknown token tried to beeing used by a host."); brokenToken = this.dToken.save(brokenToken); this.handleAgent(agentName, brokenToken); } private EAgent handleAgent(String agentName, EAgentAuthToken authToken) { EAgent dbAgent = this.dAgent.findAgentByName(agentName); if (dbAgent == null) { dbAgent = this.createNewAgent(agentName, authToken); } if ((dbAgent.getToken() == null) || !(dbAgent.getToken().equals(authToken))) { dbAgent.setToken(authToken); dbAgent.setTokenAssociationDate(DateTime.now().getMillis()); dbAgent = this.dAgent.save(dbAgent); } return dbAgent; } private EAgent createNewAgent(String agentName, EAgentAuthToken authToken) { EAgent agent = new EAgent(); agent.setName(agentName); agent.setToken(authToken); agent.setTokenAssociationDate(DateTime.now().getMillis()); return this.dAgent.save(agent); } private SecurityContext noTokenNeededCheck() { if (!this.isAuthorizationMandatory()) { return AuthorizationProvider.createSC("Agent"); } return null; } }