2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.auth.service.api;
24 import static org.onap.aaf.auth.rserv.HttpMethods.DELETE;
25 import static org.onap.aaf.auth.rserv.HttpMethods.GET;
26 import static org.onap.aaf.auth.rserv.HttpMethods.POST;
27 import static org.onap.aaf.auth.rserv.HttpMethods.PUT;
29 import java.security.Principal;
30 import java.util.Date;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
35 import org.eclipse.jetty.http.HttpStatus;
36 import org.onap.aaf.auth.direct.DirectAAFUserPass;
37 import org.onap.aaf.auth.env.AuthzTrans;
38 import org.onap.aaf.auth.layer.Result;
39 import org.onap.aaf.auth.rserv.HttpMethods;
40 import org.onap.aaf.auth.service.AAF_Service;
41 import org.onap.aaf.auth.service.Code;
42 import org.onap.aaf.auth.service.facade.AuthzFacade;
43 import org.onap.aaf.auth.service.mapper.Mapper.API;
44 import org.onap.aaf.cadi.CredVal;
45 import org.onap.aaf.cadi.CredVal.Type;
46 import org.onap.aaf.cadi.Symm;
47 import org.onap.aaf.cadi.principal.BasicPrincipal;
48 import org.onap.aaf.cadi.principal.X509Principal;
49 import org.onap.aaf.cadi.taf.basic.BasicHttpTaf;
50 import org.onap.aaf.misc.env.Env;
51 import org.onap.aaf.misc.env.TimeTaken;
54 * Initialize All Dispatches related to Credentials (AUTHN)
58 public class API_Creds {
59 // Hide Public Interface
60 private API_Creds() {}
61 // needed to validate Creds even when already Authenticated x509
65 * These will be first in the list
70 * @param directAAFUserPass
73 public static void timeSensitiveInit(Env env, AAF_Service authzAPI, AuthzFacade facade, final DirectAAFUserPass directAAFUserPass) throws Exception {
75 * Basic Auth, quick Validation
77 * Responds OK or NotAuthorized
79 authzAPI.route(env, HttpMethods.GET, "/authn/basicAuth", new Code(facade,"Is given BasicAuth valid?",true) {
83 HttpServletRequest req,
84 HttpServletResponse resp) throws Exception {
86 Principal p = trans.getUserPrincipal();
87 if (p instanceof BasicPrincipal) {
88 // the idea is that if call is made with this credential, and it's a BasicPrincipal, it's ok
89 // otherwise, it wouldn't have gotten here.
90 resp.setStatus(HttpStatus.OK_200);
91 } else if (p instanceof X509Principal) {
92 // have to check Basic Auth here, because it might be CSP.
93 String authz = req.getHeader("Authorization");
94 if (authz.startsWith("Basic ")) {
95 BasicHttpTaf bht = ((X509Principal)p).getBasicHttpTaf();
97 BasicPrincipal bp = new BasicPrincipal(authz,"");
98 CredVal cv = bht.getCredVal(bp.getDomain());
100 if (cv.validate(bp.getName(), Type.PASSWORD, bp.getCred(), null) ) {
101 resp.setStatus(HttpStatus.OK_200);
103 resp.setStatus(HttpStatus.UNAUTHORIZED_401);
107 String decoded = Symm.base64noSplit.decode(authz.substring(6));
108 int colon = decoded.indexOf(':');
109 TimeTaken tt = trans.start("Direct Validation", Env.REMOTE);
111 if (directAAFUserPass.validate(
112 decoded.substring(0,colon),
113 CredVal.Type.PASSWORD ,
114 decoded.substring(colon+1).getBytes(),trans)) {
115 resp.setStatus(HttpStatus.OK_200);
117 // DME2 at this version crashes without some sort of response
118 resp.getOutputStream().print("");
119 resp.setStatus(HttpStatus.FORBIDDEN_403);
126 } else if (p == null) {
127 trans.error().log("Transaction not Authenticated... no Principal");
128 resp.setStatus(HttpStatus.FORBIDDEN_403);
130 trans.checkpoint("Basic Auth Check Failed: This wasn't a Basic Auth Trans");
131 // For Auth Security questions, we don't give any info to client on why failed
132 resp.setStatus(HttpStatus.FORBIDDEN_403);
135 },"text/plain","*/*","*");
138 * returns whether a given Credential is valid
140 authzAPI.route(POST, "/authn/validate", API.CRED_REQ, new Code(facade,"Is given Credential valid?",true) {
144 HttpServletRequest req,
145 HttpServletResponse resp) throws Exception {
146 // will be a valid Entity. Do we need to add permission
147 //if(trans.fish("ns","password","request")) or the like
148 Result<Date> r = context.doesCredentialMatch(trans, req, resp);
150 resp.setStatus(HttpStatus.OK_200);
152 // For Security, we don't give any info out on why failed, other than forbidden
153 // Can't do "401", because that is on the call itself
154 // 403 Implies you MAY NOT Ask.
155 resp.setStatus(HttpStatus.NOT_ACCEPTABLE_406);
161 * returns whether a given Credential is valid
163 authzAPI.route(GET, "/authn/cert/id/:id", API.CERTS, new Code(facade,"Get Cert Info by ID",true) {
167 HttpServletRequest req,
168 HttpServletResponse resp) throws Exception {
170 Result<Void> r = context.getCertInfoByID(trans, req, resp, pathParam(req,":id") );
172 resp.setStatus(HttpStatus.OK_200);
174 // For Security, we don't give any info out on why failed, other than forbidden
175 resp.setStatus(HttpStatus.FORBIDDEN_403);
186 * Normal Init level APIs
192 public static void init(AAF_Service authzAPI, AuthzFacade facade) throws Exception {
194 * Create a new ID/Credential
196 authzAPI.route(POST,"/authn/cred",API.CRED_REQ,new Code(facade,"Add a New ID/Credential", true) {
198 public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
199 Result<Void> r = context.createUserCred(trans, req);
201 resp.setStatus(HttpStatus.CREATED_201);
203 context.error(trans,resp,r);
209 * gets all credentials by Namespace
211 authzAPI.route(GET, "/authn/creds/ns/:ns", API.USERS, new Code(facade,"Get Creds for a Namespace",true) {
215 HttpServletRequest req,
216 HttpServletResponse resp) throws Exception {
218 Result<Void> r = context.getCredsByNS(trans, resp, pathParam(req, "ns"));
220 resp.setStatus(HttpStatus.OK_200);
222 context.error(trans,resp,r);
229 * gets all credentials by ID
231 authzAPI.route(GET, "/authn/creds/id/:id", API.USERS, new Code(facade,"Get Creds by ID",true) {
235 HttpServletRequest req,
236 HttpServletResponse resp) throws Exception {
238 Result<Void> r = context.getCredsByID(trans, resp, pathParam(req, "id"));
240 resp.setStatus(HttpStatus.OK_200);
242 context.error(trans,resp,r);
250 * Update ID/Credential (aka reset)
252 authzAPI.route(PUT,"/authn/cred",API.CRED_REQ,new Code(facade,"Update an ID/Credential", true) {
254 public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
256 Result<Void> r = context.changeUserCred(trans, req);
258 resp.setStatus(HttpStatus.OK_200);
260 context.error(trans,resp,r);
266 * Extend ID/Credential
267 * This behavior will accelerate getting out of P1 outages due to ignoring renewal requests, or
268 * other expiration issues.
270 * Scenario is that people who are solving Password problems at night, are not necessarily those who
271 * know what the passwords are supposed to be. Also, changing Password, without changing Configurations
272 * using that password only exacerbates the P1 Issue.
274 authzAPI.route(PUT,"/authn/cred/:days",API.CRED_REQ,new Code(facade,"Extend an ID/Credential", true) {
276 public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
277 Result<Void> r = context.extendUserCred(trans, req, pathParam(req, "days"));
279 resp.setStatus(HttpStatus.OK_200);
281 context.error(trans,resp,r);
287 * Delete a ID/Credential by Object
289 authzAPI.route(DELETE,"/authn/cred",API.CRED_REQ,new Code(facade,"Delete a Credential", true) {
291 public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
292 Result<Void> r = context.deleteUserCred(trans, req);
294 resp.setStatus(HttpStatus.OK_200);
296 context.error(trans,resp,r);