ffead.server.doc
SecurityHandler.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*
17  * SecurityHandler.cpp
18  *
19  * Created on: Jun 17, 2012
20  * Author: Sumeet
21  */
22 
23 #include "SecurityHandler.h"
24 
25 Logger SecurityHandler::logger;
26 
27 SecurityHandler::SecurityHandler() {
28  logger = Logger::getLogger("SecurityHandler");
29 }
30 
31 SecurityHandler::~SecurityHandler() {
32  // TODO Auto-generated destructor stub
33 }
34 
35 bool SecurityHandler::handle(string ip_addr, HttpRequest* req, HttpResponse& res, map<string, Security> securityObjectMap,
36  long sessionTimeout, void* dlib, map<string, string> cntMap)
37 {
38  bool isContrl = false;
39  string serverUrl = "";//"http://" + ip_addr;
40  if(req->getCntxt_name()!="default" && cntMap[req->getCntxt_name()]!="true")
41  serverUrl += "/" + req->getCntxt_name();
42  string actUrl = serverUrl + req->getActUrl();
43  string userRole = req->getSession()->getAttribute("_FFEAD_USER_ACCESS_ROLE");
44  if(userRole=="")
45  {
46  userRole = "ROLE_ANONYMOUS";
47  }
48  string claz;
49  Security securityObject = securityObjectMap[req->getCntxt_name()];
50  //long sessionTimeoutVar = sessionTimeout;
51  if(securityObject.isLoginConfigured())
52  {
53  //sessionTimeoutVar = securityObject.sessTimeout;
54  }
55  SecureAspect aspect = securityObject.matchesPath(req->getActUrl());
56  if(securityObject.isLoginConfigured() && ((aspect.path!="" && aspect.role!="ROLE_ANONYMOUS")
57  || (securityObject.isLoginPage(serverUrl, actUrl) && req->getRequestParam("_ffead_security_cntxt_username")!="")))
58  {
59  logger << ("Matched secure path " + aspect.path + ", which requires role " + aspect.role) << endl;
60  if(!securityObject.isLoginPage(serverUrl, actUrl) && aspect.role!=userRole)
61  {
62  res.setHTTPResponseStatus(HTTPResponseStatus::TempRedirect);
63  res.setLocation(serverUrl+"/"+securityObject.loginUrl);
64  isContrl = true;
65  }
66  else if(securityObject.isLoginPage(serverUrl, actUrl) && req->getRequestParam("_ffead_security_cntxt_username")!="")
67  {
68  claz = securityObject.loginProvider;
69  bool validUser = false;
70  if(claz.find("file:")!=string::npos)
71  {
72  claz = req->getCntxt_root()+"/"+claz.substr(claz.find(":")+1);
73  logger << ("Auth handled by file " + claz) << endl;
74  FileAuthController* authc = new FileAuthController(claz,":");
75  if(authc->isInitialized())
76  {
77  if(authc->authenticateSecurity(req->getRequestParam("_ffead_security_cntxt_username"),
78  req->getRequestParam("_ffead_security_cntxt_password")))
79  {
80  userRole = authc->getUserRole(req->getRequestParam("_ffead_security_cntxt_username"));
81  logger << ("Valid user " + req->getRequestParam("_ffead_security_cntxt_username")
82  + ", role is " + userRole) << endl;
83  validUser = true;
84  }
85  else
86  {
87  logger << "Invalid user" << endl;
88  res.setHTTPResponseStatus(HTTPResponseStatus::Unauthorized);
89  isContrl = true;
90  }
91  }
92  else
93  {
94  logger << "Invalid user repo defined" << endl;
95  }
96  delete authc;
97  }
98  else if(claz.find("class:")!=string::npos)
99  {
100  claz = claz.substr(claz.find(":")+1);
101  claz = "getReflectionCIFor" + claz;
102  logger << ("Auth handled by class " + claz) << endl;
103  if(dlib == NULL)
104  {
105  cerr << dlerror() << endl;
106  exit(-1);
107  }
108  void *mkr = dlsym(dlib, claz.c_str());
109  if(mkr!=NULL)
110  {
111  FunPtr f = (FunPtr)mkr;
112  ClassInfo srv = f();
113  args argus;
114  Constructor ctor = srv.getConstructor(argus);
115  Reflector ref;
116  void *_temp = ref.newInstanceGVP(ctor);
117  AuthController* loginc = (AuthController*)_temp;
118  if(loginc->authenticateSecurity(req->getRequestParam("_ffead_security_cntxt_username"),
119  req->getRequestParam("_ffead_security_cntxt_password")))
120  {
121  userRole = loginc->getUserRole(req->getRequestParam("_ffead_security_cntxt_username"));
122  logger << ("Valid user " + req->getRequestParam("_ffead_security_cntxt_username")
123  + ", role is " + userRole) << endl;
124  validUser = true;
125  }
126  else
127  {
128  logger << "Invalid user" << endl;
129  res.setHTTPResponseStatus(HTTPResponseStatus::Unauthorized);
130  isContrl = true;
131  }
132  logger << "Login controller called" << endl;
133  delete loginc;
134  }
135  }
136  if(validUser && (aspect.role==userRole || securityObject.isLoginPage(serverUrl, actUrl)))
137  {
138  req->getSession()->setAttribute("_FFEAD_USER_ACCESS_ROLE", userRole);
139  res.setHTTPResponseStatus(HTTPResponseStatus::TempRedirect);
140  res.setLocation(serverUrl+"/"+securityObject.welocmeFile);
141  logger << ("Valid role " + userRole + " for path " + req->getActUrl()) << endl;
142  isContrl = true;
143  }
144  else if(!validUser)
145  {
146  req->getSession()->setAttribute("_FFEAD_USER_ACCESS_ROLE", "ROLE_ANONYMOUS");
147  res.setHTTPResponseStatus(HTTPResponseStatus::Unauthorized);
148  isContrl = true;
149  }
150  }
151  }
152  return isContrl;
153 }
154 
155 Security::Security()
156 {
157  logger = Logger::getLogger("Security");
158 }
159 
160 Security::~Security()
161 {
162 
163 }
164 
165 SecureAspect Security::matchesPath(string url)
166 {
167  bool pathval = false;
168  SecureAspect aspect;
169  for (int var = 0; var < (int)secures.size(); ++var) {
170  SecureAspect secureAspect = secures.at(var);
171  string pathurl = secureAspect.path;
172  logger << ("Checking security path " + pathurl + " against url " + url) << endl;
173  if(pathurl=="*")
174  {
175  aspect = secureAspect;
176  continue;
177  }
178  if(pathurl.find("*")==pathurl.length()-1)
179  {
180  pathurl = pathurl.substr(0, pathurl.length()-1);
181  pathval = true;
182  }
183  if(pathval && url.find(pathurl)!=string::npos)
184  {
185  aspect = secureAspect;
186  }
187  else if(!pathval && pathurl==url)
188  {
189  aspect = secureAspect;
190  }
191  }
192  return aspect;
193 }