Revision 60501
Added by Konstantina Galouni about 3 years ago
AuthorizationUtils.java | ||
---|---|---|
1 |
package eu.dnetlib.uoaadmintools.handlers.utils; |
|
2 |
|
|
3 |
import org.apache.log4j.Logger; |
|
4 |
|
|
5 |
import javax.servlet.http.Cookie; |
|
6 |
import javax.servlet.http.HttpServletRequest; |
|
7 |
import java.io.BufferedReader; |
|
8 |
import java.io.InputStreamReader; |
|
9 |
import java.io.StringReader; |
|
10 |
import java.net.HttpURLConnection; |
|
11 |
import java.net.URL; |
|
12 |
import java.util.Enumeration; |
|
13 |
|
|
14 |
import com.google.gson.Gson; |
|
15 |
|
|
16 |
/** |
|
17 |
* Created by argirok on 27/2/2018. |
|
18 |
*/ |
|
19 |
public class AuthorizationUtils { |
|
20 |
private final Logger log = Logger.getLogger(this.getClass()); |
|
21 |
private String userInfoUrl = null; |
|
22 |
// private String communityAPI =""; |
|
23 |
// List<String> adminRoles = new ArrayList<String>(Arrays.asList("Super Administrator", "Portal Administrator")); |
|
24 |
private String originServer= null; |
|
25 |
public Boolean checkCookies(HttpServletRequest request){ |
|
26 |
Boolean valid = true; |
|
27 |
String cookieValue = this.getCookie(request,"AccessToken"); |
|
28 |
if(cookieValue == null || cookieValue.isEmpty()){ |
|
29 |
log.info("no cookie available "); |
|
30 |
valid = false; |
|
31 |
}else { |
|
32 |
String headerValue = this.getHeadersInfo(request, "x-xsrf-token"); |
|
33 |
if(headerValue == null || headerValue.isEmpty()){ |
|
34 |
log.info("no header available "); |
|
35 |
valid = false; |
|
36 |
}else{ |
|
37 |
if(!cookieValue.equals(headerValue)){ |
|
38 |
log.info("no proper header or cookie "); |
|
39 |
valid = false; |
|
40 |
}else if(!hasValidOrigin(this.getHeadersInfo(request, "origin"))){ |
|
41 |
log.info("no proper origin "); |
|
42 |
valid = false; |
|
43 |
} |
|
44 |
} |
|
45 |
} |
|
46 |
return valid; |
|
47 |
} |
|
48 |
public String getToken(HttpServletRequest request){ |
|
49 |
return this.getHeadersInfo(request, "x-xsrf-token"); |
|
50 |
} |
|
51 |
private String getCookie(HttpServletRequest request, String cookieName){ |
|
52 |
if(request.getCookies() == null){ |
|
53 |
return null; |
|
54 |
} |
|
55 |
for(Cookie c: request.getCookies()){ |
|
56 |
// log.debug("cookie "+ c.getName()+ " "+ c.getValue()); |
|
57 |
if(c.getName().equals(cookieName)){ |
|
58 |
return c.getValue(); |
|
59 |
} |
|
60 |
|
|
61 |
} |
|
62 |
return null; |
|
63 |
} |
|
64 |
private String getHeadersInfo(HttpServletRequest request, String name) { |
|
65 |
|
|
66 |
Enumeration headerNames = request.getHeaderNames(); |
|
67 |
while (headerNames.hasMoreElements()) { |
|
68 |
String key = (String) headerNames.nextElement(); |
|
69 |
String value = request.getHeader(key); |
|
70 |
// log.debug(" key: "+ key+" value: "+ value); |
|
71 |
if(name.equals(key)){ |
|
72 |
return value; |
|
73 |
} |
|
74 |
} |
|
75 |
return null; |
|
76 |
} |
|
77 |
public boolean hasValidOrigin(String origin) { |
|
78 |
if (origin != null && origin.indexOf(originServer)!=-1) { |
|
79 |
return true; |
|
80 |
} |
|
81 |
log.debug("Not valid origin. Origin server is \"" + origin + "\", but expected value is \"" + originServer + "\". If the expec cted value is not right, check properties file. "); |
|
82 |
return false; |
|
83 |
} |
|
84 |
public UserInfo getUserInfo(String accessToken){ |
|
85 |
String url=userInfoUrl+accessToken; |
|
86 |
URL obj = null; |
|
87 |
String responseStr=null; |
|
88 |
// log.debug("User info url is "+url); |
|
89 |
|
|
90 |
try { |
|
91 |
obj = new URL(url); |
|
92 |
HttpURLConnection con = (HttpURLConnection) obj.openConnection(); |
|
93 |
if (con.getResponseCode() != 200) { |
|
94 |
log.debug("User info response code is: " + con.getResponseCode()); |
|
95 |
return null; |
|
96 |
} |
|
97 |
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); |
|
98 |
StringBuffer response = new StringBuffer(); |
|
99 |
String inputLine; |
|
100 |
while ((inputLine = in.readLine()) != null) { |
|
101 |
response.append(inputLine).append("\n"); |
|
102 |
} |
|
103 |
in.close(); |
|
104 |
responseStr = response.toString(); |
|
105 |
}catch(Exception e){ |
|
106 |
log.error("An error occured while trying to fetch user info ",e); |
|
107 |
return null; |
|
108 |
} |
|
109 |
return json2UserInfo(responseStr); |
|
110 |
} |
|
111 |
private UserInfo json2UserInfo(String json) { |
|
112 |
|
|
113 |
// log.debug("Try to create userInfo class from json: "+json); |
|
114 |
if (json == null){ |
|
115 |
return null; |
|
116 |
} |
|
117 |
|
|
118 |
BufferedReader br = new BufferedReader(new StringReader(json)); |
|
119 |
//convert the json string back to object |
|
120 |
Gson gson = new Gson(); |
|
121 |
UserInfo userInfo = null; |
|
122 |
try { |
|
123 |
userInfo = gson.fromJson(br, UserInfo.class); |
|
124 |
}catch(Exception e){ |
|
125 |
log.debug("Error in parsing json response. Given json is : "+json, e); |
|
126 |
return null; |
|
127 |
} |
|
128 |
|
|
129 |
// log.debug("Original response.........: "+userInfo.toString()); |
|
130 |
try { |
|
131 |
if(userInfo != null && userInfo.getEdu_person_entitlements() != null ) { |
|
132 |
|
|
133 |
for (int i = 0; i < userInfo.getEdu_person_entitlements().size(); i++) { |
|
134 |
String role = userInfo.getEdu_person_entitlements().get(i); |
|
135 |
// log.debug("AAI role: "+role); |
|
136 |
role = role.split(":")[role.split(":").length-1]; |
|
137 |
role = role.replace("+"," "); |
|
138 |
// log.debug("Adding parsed role : "+role); |
|
139 |
userInfo.getEdu_person_entitlements().set(i,role); |
|
140 |
} |
|
141 |
} |
|
142 |
}catch(Exception e){ |
|
143 |
log.debug("Error in parsing Edu_person_entitlements : ",e); |
|
144 |
return null; |
|
145 |
} |
|
146 |
// log.debug("After handling roles : "+userInfo.toString()); |
|
147 |
|
|
148 |
|
|
149 |
return userInfo; |
|
150 |
} |
|
151 |
public boolean isAuthorized(String token) { |
|
152 |
UserInfo userInfo = getUserInfo(token); |
|
153 |
if (userInfo != null ) { |
|
154 |
return true; |
|
155 |
} else { |
|
156 |
log.debug(" User has no Valid UserInfo"); |
|
157 |
return false; |
|
158 |
} |
|
159 |
|
|
160 |
} |
|
161 |
|
|
162 |
public String getUserInfoUrl() { |
|
163 |
return userInfoUrl; |
|
164 |
} |
|
165 |
|
|
166 |
public String getOriginServer() { |
|
167 |
return originServer; |
|
168 |
} |
|
169 |
|
|
170 |
public void setUserInfoUrl(String userInfoUrl) { |
|
171 |
this.userInfoUrl = userInfoUrl; |
|
172 |
} |
|
173 |
|
|
174 |
public void setOriginServer(String originServer) { |
|
175 |
this.originServer = originServer; |
|
176 |
} |
|
177 |
// private boolean hasRole(List<String> givenRoles, List<String> authorizedRoles) { |
|
178 |
// log.debug("It's registered with role " + givenRoles); |
|
179 |
// for (String gRole : givenRoles) { |
|
180 |
// if (authorizedRoles.indexOf(gRole) != -1) { |
|
181 |
// return true; |
|
1 |
//package eu.dnetlib.uoaadmintools.handlers.utils; |
|
2 |
// |
|
3 |
//import org.apache.log4j.Logger; |
|
4 |
// |
|
5 |
//import javax.servlet.http.Cookie; |
|
6 |
//import javax.servlet.http.HttpServletRequest; |
|
7 |
//import java.io.BufferedReader; |
|
8 |
//import java.io.InputStreamReader; |
|
9 |
//import java.io.StringReader; |
|
10 |
//import java.net.HttpURLConnection; |
|
11 |
//import java.net.URL; |
|
12 |
//import java.util.Enumeration; |
|
13 |
// |
|
14 |
//import com.google.gson.Gson; |
|
15 |
// |
|
16 |
///** |
|
17 |
// * Created by argirok on 27/2/2018. |
|
18 |
// */ |
|
19 |
//public class AuthorizationUtils { |
|
20 |
// private final Logger log = Logger.getLogger(this.getClass()); |
|
21 |
// private String userInfoUrl = null; |
|
22 |
//// private String communityAPI =""; |
|
23 |
//// List<String> adminRoles = new ArrayList<String>(Arrays.asList("Super Administrator", "Portal Administrator")); |
|
24 |
// private String originServer= null; |
|
25 |
// public Boolean checkCookies(HttpServletRequest request){ |
|
26 |
// Boolean valid = true; |
|
27 |
// String cookieValue = this.getCookie(request,"AccessToken"); |
|
28 |
// if(cookieValue == null || cookieValue.isEmpty()){ |
|
29 |
// log.info("no cookie available "); |
|
30 |
// valid = false; |
|
31 |
// }else { |
|
32 |
// String headerValue = this.getHeadersInfo(request, "x-xsrf-token"); |
|
33 |
// if(headerValue == null || headerValue.isEmpty()){ |
|
34 |
// log.info("no header available "); |
|
35 |
// valid = false; |
|
36 |
// }else{ |
|
37 |
// if(!cookieValue.equals(headerValue)){ |
|
38 |
// log.info("no proper header or cookie "); |
|
39 |
// valid = false; |
|
40 |
// }else if(!hasValidOrigin(this.getHeadersInfo(request, "origin"))){ |
|
41 |
// log.info("no proper origin "); |
|
42 |
// valid = false; |
|
43 |
// } |
|
182 | 44 |
// } |
183 | 45 |
// } |
184 |
// log.debug("Not Authorized. Authorized roles are" + authorizedRoles); |
|
185 |
// return false; |
|
46 |
// return valid; |
|
47 |
// } |
|
48 |
// public String getToken(HttpServletRequest request){ |
|
49 |
// return this.getHeadersInfo(request, "x-xsrf-token"); |
|
50 |
// } |
|
51 |
// private String getCookie(HttpServletRequest request, String cookieName){ |
|
52 |
// if(request.getCookies() == null){ |
|
53 |
// return null; |
|
54 |
// } |
|
55 |
// for(Cookie c: request.getCookies()){ |
|
56 |
//// log.debug("cookie "+ c.getName()+ " "+ c.getValue()); |
|
57 |
// if(c.getName().equals(cookieName)){ |
|
58 |
// return c.getValue(); |
|
59 |
// } |
|
186 | 60 |
// |
61 |
// } |
|
62 |
// return null; |
|
187 | 63 |
// } |
188 |
// private boolean isCommunityManager(String community, String email) {
|
|
64 |
// private String getHeadersInfo(HttpServletRequest request, String name) {
|
|
189 | 65 |
// |
190 |
// CommunityInfo communityInfo = getCommunityInfo(community);
|
|
191 |
// if(communityInfo != null && communityInfo.getManagers() != null ) {
|
|
192 |
// |
|
193 |
// for (int i = 0; i < communityInfo.getManagers().size(); i++) {
|
|
194 |
// String manager = communityInfo.getManagers().get(i);
|
|
195 |
// log.debug("Community manager: "+manager);
|
|
196 |
// |
|
66 |
// Enumeration headerNames = request.getHeaderNames();
|
|
67 |
// while (headerNames.hasMoreElements()) {
|
|
68 |
// String key = (String) headerNames.nextElement();
|
|
69 |
// String value = request.getHeader(key);
|
|
70 |
//// log.debug(" key: "+ key+" value: "+ value);
|
|
71 |
// if(name.equals(key)){
|
|
72 |
// return value;
|
|
197 | 73 |
// } |
198 | 74 |
// } |
75 |
// return null; |
|
76 |
// } |
|
77 |
// public boolean hasValidOrigin(String origin) { |
|
78 |
// if (origin != null && origin.indexOf(originServer)!=-1) { |
|
79 |
// return true; |
|
80 |
// } |
|
81 |
// log.debug("Not valid origin. Origin server is \"" + origin + "\", but expected value is \"" + originServer + "\". If the expec cted value is not right, check properties file. "); |
|
199 | 82 |
// return false; |
200 |
// |
|
201 | 83 |
// } |
202 |
// private CommunityInfo getCommunityInfo(String community) {
|
|
203 |
// String url = userInfoUrl + community;
|
|
84 |
// public UserInfo getUserInfo(String accessToken){
|
|
85 |
// String url=userInfoUrl+accessToken;
|
|
204 | 86 |
// URL obj = null; |
205 |
// String responseStr = null;
|
|
206 |
// log.debug("Community info url is " + url);
|
|
87 |
// String responseStr=null;
|
|
88 |
//// log.debug("User info url is "+url);
|
|
207 | 89 |
// |
208 | 90 |
// try { |
209 | 91 |
// obj = new URL(url); |
210 | 92 |
// HttpURLConnection con = (HttpURLConnection) obj.openConnection(); |
211 |
// log.debug("User info response code is: " + con.getResponseCode()); |
|
212 | 93 |
// if (con.getResponseCode() != 200) { |
94 |
// log.debug("User info response code is: " + con.getResponseCode()); |
|
213 | 95 |
// return null; |
214 | 96 |
// } |
215 | 97 |
// BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); |
... | ... | |
220 | 102 |
// } |
221 | 103 |
// in.close(); |
222 | 104 |
// responseStr = response.toString(); |
223 |
// } catch (Exception e) {
|
|
224 |
// log.error("An error occured while trying to fetch user info ", e);
|
|
105 |
// }catch(Exception e){
|
|
106 |
// log.error("An error occured while trying to fetch user info ",e); |
|
225 | 107 |
// return null; |
226 | 108 |
// } |
227 |
// return json2CommunityInfo(community);
|
|
109 |
// return json2UserInfo(responseStr);
|
|
228 | 110 |
// } |
229 |
// private CommunityInfo json2CommunityInfo(String json){
|
|
111 |
// private UserInfo json2UserInfo(String json) {
|
|
230 | 112 |
// |
231 |
// log.debug("Try to create CommunityInfo class from json: "+json);
|
|
113 |
//// log.debug("Try to create userInfo class from json: "+json);
|
|
232 | 114 |
// if (json == null){ |
233 | 115 |
// return null; |
234 | 116 |
// } |
... | ... | |
236 | 118 |
// BufferedReader br = new BufferedReader(new StringReader(json)); |
237 | 119 |
// //convert the json string back to object |
238 | 120 |
// Gson gson = new Gson(); |
239 |
// CommunityInfo communityInfo = null;
|
|
121 |
// UserInfo userInfo = null;
|
|
240 | 122 |
// try { |
241 |
// communityInfo = gson.fromJson(br, CommunityInfo.class);
|
|
123 |
// userInfo = gson.fromJson(br, UserInfo.class);
|
|
242 | 124 |
// }catch(Exception e){ |
243 | 125 |
// log.debug("Error in parsing json response. Given json is : "+json, e); |
244 | 126 |
// return null; |
245 | 127 |
// } |
246 | 128 |
// |
247 |
// log.debug("Original response.........: "+communityInfo.toString()); |
|
129 |
//// log.debug("Original response.........: "+userInfo.toString()); |
|
130 |
// try { |
|
131 |
// if(userInfo != null && userInfo.getEdu_person_entitlements() != null ) { |
|
248 | 132 |
// |
133 |
// for (int i = 0; i < userInfo.getEdu_person_entitlements().size(); i++) { |
|
134 |
// String role = userInfo.getEdu_person_entitlements().get(i); |
|
135 |
//// log.debug("AAI role: "+role); |
|
136 |
// role = role.split(":")[role.split(":").length-1]; |
|
137 |
// role = role.replace("+"," "); |
|
138 |
//// log.debug("Adding parsed role : "+role); |
|
139 |
// userInfo.getEdu_person_entitlements().set(i,role); |
|
140 |
// } |
|
141 |
// } |
|
142 |
// }catch(Exception e){ |
|
143 |
// log.debug("Error in parsing Edu_person_entitlements : ",e); |
|
144 |
// return null; |
|
145 |
// } |
|
146 |
//// log.debug("After handling roles : "+userInfo.toString()); |
|
249 | 147 |
// |
250 | 148 |
// |
251 |
// return communityInfo;
|
|
149 |
// return userInfo;
|
|
252 | 150 |
// } |
253 |
} |
|
151 |
// public boolean isAuthorized(String token) { |
|
152 |
// UserInfo userInfo = getUserInfo(token); |
|
153 |
// if (userInfo != null ) { |
|
154 |
// return true; |
|
155 |
// } else { |
|
156 |
// log.debug(" User has no Valid UserInfo"); |
|
157 |
// return false; |
|
158 |
// } |
|
159 |
// |
|
160 |
// } |
|
161 |
// |
|
162 |
// public String getUserInfoUrl() { |
|
163 |
// return userInfoUrl; |
|
164 |
// } |
|
165 |
// |
|
166 |
// public String getOriginServer() { |
|
167 |
// return originServer; |
|
168 |
// } |
|
169 |
// |
|
170 |
// public void setUserInfoUrl(String userInfoUrl) { |
|
171 |
// this.userInfoUrl = userInfoUrl; |
|
172 |
// } |
|
173 |
// |
|
174 |
// public void setOriginServer(String originServer) { |
|
175 |
// this.originServer = originServer; |
|
176 |
// } |
|
177 |
// // private boolean hasRole(List<String> givenRoles, List<String> authorizedRoles) { |
|
178 |
//// log.debug("It's registered with role " + givenRoles); |
|
179 |
//// for (String gRole : givenRoles) { |
|
180 |
//// if (authorizedRoles.indexOf(gRole) != -1) { |
|
181 |
//// return true; |
|
182 |
//// } |
|
183 |
//// } |
|
184 |
//// log.debug("Not Authorized. Authorized roles are" + authorizedRoles); |
|
185 |
//// return false; |
|
186 |
//// |
|
187 |
//// } |
|
188 |
//// private boolean isCommunityManager(String community, String email) { |
|
189 |
//// |
|
190 |
//// CommunityInfo communityInfo = getCommunityInfo(community); |
|
191 |
//// if(communityInfo != null && communityInfo.getManagers() != null ) { |
|
192 |
//// |
|
193 |
//// for (int i = 0; i < communityInfo.getManagers().size(); i++) { |
|
194 |
//// String manager = communityInfo.getManagers().get(i); |
|
195 |
//// log.debug("Community manager: "+manager); |
|
196 |
//// |
|
197 |
//// } |
|
198 |
//// } |
|
199 |
//// return false; |
|
200 |
//// |
|
201 |
//// } |
|
202 |
//// private CommunityInfo getCommunityInfo(String community) { |
|
203 |
//// String url = userInfoUrl + community; |
|
204 |
//// URL obj = null; |
|
205 |
//// String responseStr = null; |
|
206 |
//// log.debug("Community info url is " + url); |
|
207 |
//// |
|
208 |
//// try { |
|
209 |
//// obj = new URL(url); |
|
210 |
//// HttpURLConnection con = (HttpURLConnection) obj.openConnection(); |
|
211 |
//// log.debug("User info response code is: " + con.getResponseCode()); |
|
212 |
//// if (con.getResponseCode() != 200) { |
|
213 |
//// return null; |
|
214 |
//// } |
|
215 |
//// BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); |
|
216 |
//// StringBuffer response = new StringBuffer(); |
|
217 |
//// String inputLine; |
|
218 |
//// while ((inputLine = in.readLine()) != null) { |
|
219 |
//// response.append(inputLine).append("\n"); |
|
220 |
//// } |
|
221 |
//// in.close(); |
|
222 |
//// responseStr = response.toString(); |
|
223 |
//// } catch (Exception e) { |
|
224 |
//// log.error("An error occured while trying to fetch user info ", e); |
|
225 |
//// return null; |
|
226 |
//// } |
|
227 |
//// return json2CommunityInfo(community); |
|
228 |
//// } |
|
229 |
//// private CommunityInfo json2CommunityInfo(String json){ |
|
230 |
//// |
|
231 |
//// log.debug("Try to create CommunityInfo class from json: "+json); |
|
232 |
//// if (json == null){ |
|
233 |
//// return null; |
|
234 |
//// } |
|
235 |
//// |
|
236 |
//// BufferedReader br = new BufferedReader(new StringReader(json)); |
|
237 |
//// //convert the json string back to object |
|
238 |
//// Gson gson = new Gson(); |
|
239 |
//// CommunityInfo communityInfo = null; |
|
240 |
//// try { |
|
241 |
//// communityInfo = gson.fromJson(br, CommunityInfo.class); |
|
242 |
//// }catch(Exception e){ |
|
243 |
//// log.debug("Error in parsing json response. Given json is : "+json, e); |
|
244 |
//// return null; |
|
245 |
//// } |
|
246 |
//// |
|
247 |
//// log.debug("Original response.........: "+communityInfo.toString()); |
|
248 |
//// |
|
249 |
//// |
|
250 |
//// |
|
251 |
//// return communityInfo; |
|
252 |
//// } |
|
253 |
//} |
Also available in: Unified diff
[Trunk | Admin Tools]:
1. pom.xml: Added dependency for spring security.
2. UoaAdminToolsApplication.java: Import AuthorizationConfiguration.class | Remove SecurityConfig.class from @EnableConfigurationProperties.
3. UoaAdminToolsConfiguration.java: Comment "addInterceptors()" method calling AuthorizationHandler with SecurityConfig.
4. SecurityConfig.java & AuthorizationHandler.java & AuthorizationUtils.java & CommunityInfo.java & UserInfo.java: Commented all contents of these files (files will be deleted in coming commit).
5. PortalSubscribersController.java: Comment imports from commeted files.
6. Notifications.java: Added field "aaiId" get getters and setters.
7. NotificationsController.java:
a. Method "getNotifications()" is replaced by "getNotificationsForUser()" (/community/{pid}/notifications) - returns notification settings only for user who made the request (uoa-authorization-li$
b. Path changed for method "getNotifications()": /community/{pid}/notifications/all
c. Remove "@RequestBody String email" parameter from method "deleteNotification()" - get email from user who made the request (uoa-authorization-library).
d. In method "saveNotification()" get aaiId and email from user who made the request (uoa-authorization-library).
e. Added checks and throw Exceptions in all methods.
f. Added @PreAuthorize
Portal Admins: "getNotifications()" (/community/{pid}/notifications/all)
Portal Admins - Curators - Managers: "getNotificationsForUser()" (/community/{pid}/notifications), "deleteNotification()" (/community/{pid}/notifications), "saveNotification()" (/communit$
8. ExploreController.java:
a. Added checks and throw Exceptions in all methods.
b. Added @PreAuthorize
Portal Admins: "updateExplore()" (/explore/update), "insertExplore()" (/explore/save), "deleteExplore()" (/explore/delete).
9. ConnectController.java:
a. Added checks and throw Exceptions in all methods.
b. Added @PreAuthorize
Portal Admins: "updateConnect()" (/connect/update), "insertConnect()" (/connect/save), "deleteConnect()" (/connect/delete).
c. Commented methods "getLayoutForConnect()" and "updateLayoutForConnect()" (/connect/{pid}/layout).
10. CommunityController.java:
a. Added checks and throw Exceptions in all methods.
b. Added @PreAuthorize
Portal Admins: "updateCommunity()" (/community/update), "insertCommunity()" (/community/save), "deleteCommunity()" (/community/delete).
Portal Admin - Curators - Managers: "updateLayoutForCommunity()" (/community/{pid}/layout).
11. CuratorController.java:
a. In "insertCurator() (/curator) set _id field with aaiId from user who made the request (uoa-authorization-library).
b. Added @PreAuthorize
Authenticated users: "getCuratorById()" (/curator/{id}), "insertCurator()" (/curator).
Portal Admins: "deleteCurators()" (/curator).