X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=auth%2Fauth-oauth%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Foauth%2Fservice%2FOAuthService.java;h=1d926a74917d43a36533e4ce9ef05c422aac4939;hb=4b5a7d721d994a49057e9bfb403c7bff1b376660;hp=0064e224451b659b151d974bf0fece5c36e8fdf9;hpb=824dc7b5fc0e1ccdf7f460479aff344727f0f01e;p=aaf%2Fauthz.git diff --git a/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java b/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java index 0064e224..1d926a74 100644 --- a/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java +++ b/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java @@ -54,248 +54,248 @@ import org.onap.aaf.misc.env.APIException; import aafoauth.v2_0.Introspect; public class OAuthService { - - private static final int TOK_EXP = 60*60*1000; // 1 hour, millis. + + private static final int TOK_EXP = 60*60*1000; // 1 hour, millis. - public enum TOKEN_TYPE {unknown,bearer,refresh} - public enum GRANT_TYPE {unknown,password,client_credentials,refresh_token}; - public enum CLIENT_TYPE {unknown,confidential}; - - // Additional Expires - private final DAO[] daos; - public final OAuthTokenDAO tokenDAO; - private final DirectAAFUserPass directUserPass; - private final TokenClientFactory tcf; - private TokenClient altIntrospectClient; - private String altDomain; - private final JSONPermLoader permLoader; + public enum TOKEN_TYPE {unknown,bearer,refresh} + public enum GRANT_TYPE {unknown,password,client_credentials,refresh_token}; + public enum CLIENT_TYPE {unknown,confidential}; + + // Additional Expires + private final DAO[] daos; + public final OAuthTokenDAO tokenDAO; + private final DirectAAFUserPass directUserPass; + private final TokenClientFactory tcf; + private TokenClient altIntrospectClient; + private String altDomain; + private final JSONPermLoader permLoader; - // If we add more CAs, may want to parameterize + // If we add more CAs, may want to parameterize - @SuppressWarnings("unchecked") - public OAuthService(final Access access, final AuthzTrans trans, final Question q) throws APIException, IOException { - permLoader = JSONPermLoaderFactory.direct(q); - tokenDAO = new OAuthTokenDAO(trans, q.historyDAO); - daos =(DAO[]) new DAO[] { - tokenDAO - }; - try { - String alt_url = access.getProperty(Config.AAF_ALT_OAUTH2_INTROSPECT_URL,null); - if(alt_url!=null) { - tcf = TokenClientFactory.instance(access); - String[] split = Split.split(',', alt_url); - int timeout = split.length>1?Integer.parseInt(split[1]):3000; - altIntrospectClient = tcf.newClient(split[0], timeout); - altIntrospectClient.client_creds(access.getProperty(Config.AAF_ALT_CLIENT_ID,null), - access.getProperty(Config.AAF_ALT_CLIENT_SECRET,null)); - altDomain = '@'+access.getProperty(Config.AAF_ALT_OAUTH2_DOMAIN,null); - } else { - tcf = null; - } - directUserPass = new DirectAAFUserPass(trans.env(), q); - } catch (GeneralSecurityException | CadiException | LocatorException e) { - throw new APIException("Could not construct TokenClientFactory",e); - } - - } + @SuppressWarnings("unchecked") + public OAuthService(final Access access, final AuthzTrans trans, final Question q) throws APIException, IOException { + permLoader = JSONPermLoaderFactory.direct(q); + tokenDAO = new OAuthTokenDAO(trans, q.historyDAO); + daos =(DAO[]) new DAO[] { + tokenDAO + }; + try { + String alt_url = access.getProperty(Config.AAF_ALT_OAUTH2_INTROSPECT_URL,null); + if(alt_url!=null) { + tcf = TokenClientFactory.instance(access); + String[] split = Split.split(',', alt_url); + int timeout = split.length>1?Integer.parseInt(split[1]):3000; + altIntrospectClient = tcf.newClient(split[0], timeout); + altIntrospectClient.client_creds(access.getProperty(Config.AAF_ALT_CLIENT_ID,null), + access.getProperty(Config.AAF_ALT_CLIENT_SECRET,null)); + altDomain = '@'+access.getProperty(Config.AAF_ALT_OAUTH2_DOMAIN,null); + } else { + tcf = null; + } + directUserPass = new DirectAAFUserPass(trans.env(), q); + } catch (GeneralSecurityException | CadiException | LocatorException e) { + throw new APIException("Could not construct TokenClientFactory",e); + } + + } - public Result validate(AuthzTrans trans, OCreds creds) { - if(directUserPass.validate(creds.username, Type.PASSWORD, creds.password, trans)) { - return Result.ok(); - } else { - return Result.err(Result.ERR_Security, "Invalid Credential for ",creds.username); - } - } + public Result validate(AuthzTrans trans, OCreds creds) { + if(directUserPass.validate(creds.username, Type.PASSWORD, creds.password, trans)) { + return Result.ok(); + } else { + return Result.err(Result.ERR_Security, "Invalid Credential for ",creds.username); + } + } - public Result createToken(AuthzTrans trans, HttpServletRequest req, OAuthTokenDAO.Data odd, Holder hgt) { - switch(hgt.get()) { - case client_credentials: - case password: - return createBearerToken(trans, odd); - case refresh_token: - return refreshBearerToken(trans, odd); - default: - return Result.err(Result.ERR_BadData, "Unknown Grant Type"); - } - } - - private Result createBearerToken(AuthzTrans trans, OAuthTokenDAO.Data odd) { - if(odd.user==null) { - odd.user = trans.user(); - } - odd.id = AAFToken.toToken(UUID.randomUUID()); - odd.refresh = AAFToken.toToken(UUID.randomUUID()); - odd.active = true; - long exp; - odd.expires = new Date(exp=(System.currentTimeMillis()+TOK_EXP)); - odd.exp_sec = exp/1000; - odd.req_ip = trans.ip(); - - try { - Result rd = loadToken(trans, odd); - if(rd.notOK()) { - return rd; - } - } catch (APIException | CadiException e) { - return Result.err(e); - } - return tokenDAO.create(trans, odd); - } - - private Result loadToken(AuthzTrans trans, Data odd) throws APIException, CadiException { - Result rs = permLoader.loadJSONPerms(trans,odd.user,odd.scopes(false)); - if(rs.isOK()) { - odd.content = rs.value; - odd.type = TOKEN_TYPE.bearer.ordinal(); - return Result.ok(odd); - } else if(rs.status == Result.ERR_NotFound || rs.status==Status.ERR_UserRoleNotFound) { - odd.type = TOKEN_TYPE.bearer.ordinal(); - return Result.ok(odd); - } else { - return Result.err(Result.ERR_Backend,"Error accessing AAF Info: %s",rs.errorString()); - } - } - - + public Result createToken(AuthzTrans trans, HttpServletRequest req, OAuthTokenDAO.Data odd, Holder hgt) { + switch(hgt.get()) { + case client_credentials: + case password: + return createBearerToken(trans, odd); + case refresh_token: + return refreshBearerToken(trans, odd); + default: + return Result.err(Result.ERR_BadData, "Unknown Grant Type"); + } + } + + private Result createBearerToken(AuthzTrans trans, OAuthTokenDAO.Data odd) { + if(odd.user==null) { + odd.user = trans.user(); + } + odd.id = AAFToken.toToken(UUID.randomUUID()); + odd.refresh = AAFToken.toToken(UUID.randomUUID()); + odd.active = true; + long exp; + odd.expires = new Date(exp=(System.currentTimeMillis()+TOK_EXP)); + odd.exp_sec = exp/1000; + odd.req_ip = trans.ip(); + + try { + Result rd = loadToken(trans, odd); + if(rd.notOK()) { + return rd; + } + } catch (APIException | CadiException e) { + return Result.err(e); + } + return tokenDAO.create(trans, odd); + } + + private Result loadToken(AuthzTrans trans, Data odd) throws APIException, CadiException { + Result rs = permLoader.loadJSONPerms(trans,odd.user,odd.scopes(false)); + if(rs.isOK()) { + odd.content = rs.value; + odd.type = TOKEN_TYPE.bearer.ordinal(); + return Result.ok(odd); + } else if(rs.status == Result.ERR_NotFound || rs.status==Status.ERR_UserRoleNotFound) { + odd.type = TOKEN_TYPE.bearer.ordinal(); + return Result.ok(odd); + } else { + return Result.err(Result.ERR_Backend,"Error accessing AAF Info: %s",rs.errorString()); + } + } + + - private Result refreshBearerToken(AuthzTrans trans, Data odd) { - Result> rld = tokenDAO.readByUser(trans, trans.user()); - if(rld.notOK()) { - return Result.err(rld); - } - if(rld.isEmpty()) { - return Result.err(Result.ERR_NotFound,"Data not Found for %1 %2",trans.user(),odd.refresh==null?"":odd.refresh.toString()); - } - Data token = null; - for(Data d : rld.value) { - if(d.refresh.equals(odd.refresh)) { - token = d; - boolean scopesNE = false; - Set scopes = odd.scopes(false); - if(scopes.size()>0) { // only check if Scopes listed, RFC 6749, Section 6 - if(scopesNE=!(scopes.size() == d.scopes(false).size())) { - for(String s : odd.scopes(false)) { - if(!d.scopes(false).contains(s)) { - scopesNE=true; - break; - } - } - } - if(scopesNE) { - return Result.err(Result.ERR_BadData,"Requested Scopes do not match existing Token"); - } - } - break; - } - } - - if(token==null) { - trans.audit().printf("Duplicate Refresh Token (%s) attempted for %s. Possible Replay Attack",odd.refresh.toString(),trans.user()); - return Result.err(Result.ERR_Security,"Invalid Refresh Token"); - } else { - // Got the Result - Data deleteMe = new Data(); - deleteMe.id = token.id; - token.id = AAFToken.toToken(UUID.randomUUID()); - token.client_id = trans.user(); - token.refresh = AAFToken.toToken(UUID.randomUUID()); - long exp; - token.expires = new Date(exp=(System.currentTimeMillis()+TOK_EXP)); - token.exp_sec = exp/1000; - token.req_ip = trans.ip(); - Result rd = tokenDAO.create(trans, token); - if(rd.notOK()) { - return Result.err(rd); - } - Result rv = tokenDAO.delete(trans, deleteMe,false); - if(rv.notOK()) { - trans.error().log("Unable to delete token", token); - } - } - return Result.ok(token); - } + private Result refreshBearerToken(AuthzTrans trans, Data odd) { + Result> rld = tokenDAO.readByUser(trans, trans.user()); + if(rld.notOK()) { + return Result.err(rld); + } + if(rld.isEmpty()) { + return Result.err(Result.ERR_NotFound,"Data not Found for %1 %2",trans.user(),odd.refresh==null?"":odd.refresh.toString()); + } + Data token = null; + for(Data d : rld.value) { + if(d.refresh.equals(odd.refresh)) { + token = d; + boolean scopesNE = false; + Set scopes = odd.scopes(false); + if(scopes.size()>0) { // only check if Scopes listed, RFC 6749, Section 6 + if(scopesNE=!(scopes.size() == d.scopes(false).size())) { + for(String s : odd.scopes(false)) { + if(!d.scopes(false).contains(s)) { + scopesNE=true; + break; + } + } + } + if(scopesNE) { + return Result.err(Result.ERR_BadData,"Requested Scopes do not match existing Token"); + } + } + break; + } + } + + if(token==null) { + trans.audit().printf("Duplicate Refresh Token (%s) attempted for %s. Possible Replay Attack",odd.refresh.toString(),trans.user()); + return Result.err(Result.ERR_Security,"Invalid Refresh Token"); + } else { + // Got the Result + Data deleteMe = new Data(); + deleteMe.id = token.id; + token.id = AAFToken.toToken(UUID.randomUUID()); + token.client_id = trans.user(); + token.refresh = AAFToken.toToken(UUID.randomUUID()); + long exp; + token.expires = new Date(exp=(System.currentTimeMillis()+TOK_EXP)); + token.exp_sec = exp/1000; + token.req_ip = trans.ip(); + Result rd = tokenDAO.create(trans, token); + if(rd.notOK()) { + return Result.err(rd); + } + Result rv = tokenDAO.delete(trans, deleteMe,false); + if(rv.notOK()) { + trans.error().log("Unable to delete token", token); + } + } + return Result.ok(token); + } - public Result introspect(AuthzTrans trans, String token) { - Result> rld; - try { - UUID uuid = AAFToken.fromToken(token); - if(uuid==null) { // not an AAF Token - // Attempt to get Alternative Token - if(altIntrospectClient!=null) { - org.onap.aaf.cadi.client.Result rai = altIntrospectClient.introspect(token); - if(rai.isOK()) { - Introspect in = rai.value; - if(in.getExp()==null) { - trans.audit().printf("Alt OAuth sent back inactive, empty token: requesting_id,%s,access_token=%s,ip=%s\n",trans.user(),token,trans.ip()); - } - long expires = in.getExp()*1000; - if(in.isActive() && expires>System.currentTimeMillis()) { - // We have a good Token, modify to be Fully Qualified - String fqid = in.getUsername()+altDomain; - // read contents - rld = tokenDAO.read(trans, token); - if(rld.isOKhasData()) { - Data td = rld.value.get(0); - in.setContent(td.content); - } else { - Data td = new Data(); - td.id = token; - td.client_id = in.getClientId(); - td.user = fqid; - td.active=true; - td.type = TOKEN_TYPE.bearer.ordinal(); - td.expires = new Date(expires); - td.exp_sec = in.getExp(); - Set scopes = td.scopes(true); - if(in.getScope()!=null) { - for(String s : Split.split(' ', in.getScope())) { - scopes.add(s); - } - } - // td.state = nothing to add at this point - td.req_ip = trans.ip(); - trans.checkpoint(td.user + ':' + td.client_id + ", " + td.id); - return loadToken(trans, td); - } - } -// System.out.println(rai.value.getClientId()); - } else { - trans.audit().printf("Alt OAuth rejects: requesting_id,%s,access_token=%s,ip=%s,code=%d,error=%s\n",trans.user(),token,trans.ip(),rai.code,rai.error); - } - } else { - trans.audit().printf("Bad Token: requesting_id,%s,access_token=%s,ip=%s\n",trans.user(),token,trans.ip()); - } - return Result.err(Result.ERR_Denied,"Bad Token"); - } else { - return dbIntrospect(trans,token); - } - } catch (CadiException | APIException | LocatorException e) { - return Result.err(e); - } - } + public Result introspect(AuthzTrans trans, String token) { + Result> rld; + try { + UUID uuid = AAFToken.fromToken(token); + if(uuid==null) { // not an AAF Token + // Attempt to get Alternative Token + if(altIntrospectClient!=null) { + org.onap.aaf.cadi.client.Result rai = altIntrospectClient.introspect(token); + if(rai.isOK()) { + Introspect in = rai.value; + if(in.getExp()==null) { + trans.audit().printf("Alt OAuth sent back inactive, empty token: requesting_id,%s,access_token=%s,ip=%s\n",trans.user(),token,trans.ip()); + } + long expires = in.getExp()*1000; + if(in.isActive() && expires>System.currentTimeMillis()) { + // We have a good Token, modify to be Fully Qualified + String fqid = in.getUsername()+altDomain; + // read contents + rld = tokenDAO.read(trans, token); + if(rld.isOKhasData()) { + Data td = rld.value.get(0); + in.setContent(td.content); + } else { + Data td = new Data(); + td.id = token; + td.client_id = in.getClientId(); + td.user = fqid; + td.active=true; + td.type = TOKEN_TYPE.bearer.ordinal(); + td.expires = new Date(expires); + td.exp_sec = in.getExp(); + Set scopes = td.scopes(true); + if(in.getScope()!=null) { + for(String s : Split.split(' ', in.getScope())) { + scopes.add(s); + } + } + // td.state = nothing to add at this point + td.req_ip = trans.ip(); + trans.checkpoint(td.user + ':' + td.client_id + ", " + td.id); + return loadToken(trans, td); + } + } +// System.out.println(rai.value.getClientId()); + } else { + trans.audit().printf("Alt OAuth rejects: requesting_id,%s,access_token=%s,ip=%s,code=%d,error=%s\n",trans.user(),token,trans.ip(),rai.code,rai.error); + } + } else { + trans.audit().printf("Bad Token: requesting_id,%s,access_token=%s,ip=%s\n",trans.user(),token,trans.ip()); + } + return Result.err(Result.ERR_Denied,"Bad Token"); + } else { + return dbIntrospect(trans,token); + } + } catch (CadiException | APIException | LocatorException e) { + return Result.err(e); + } + } - public Result dbIntrospect(final AuthzTrans trans, final String token) { - Result> rld = tokenDAO.read(trans, token); - if(rld.notOKorIsEmpty()) { - return Result.err(rld); - } - OAuthTokenDAO.Data odd = rld.value.get(0); - trans.checkpoint(odd.user + ':' + odd.client_id + ", " + odd.id); - if(odd.active) { - if(odd.expires.before(trans.now())) { - return Result.err(Result.ERR_Policy,"Token %1 has expired",token); - } - return Result.ok(rld.value.get(0)); // ok keyed on id/token. - } else { - return Result.err(Result.ERR_Denied,"Token %1 is inactive",token); - } - } + public Result dbIntrospect(final AuthzTrans trans, final String token) { + Result> rld = tokenDAO.read(trans, token); + if(rld.notOKorIsEmpty()) { + return Result.err(rld); + } + OAuthTokenDAO.Data odd = rld.value.get(0); + trans.checkpoint(odd.user + ':' + odd.client_id + ", " + odd.id); + if(odd.active) { + if(odd.expires.before(trans.now())) { + return Result.err(Result.ERR_Policy,"Token %1 has expired",token); + } + return Result.ok(rld.value.get(0)); // ok keyed on id/token. + } else { + return Result.err(Result.ERR_Denied,"Token %1 is inactive",token); + } + } - public void close() { - for(DAO dao : daos) { - dao.close(NullTrans.singleton()); - } - } + public void close() { + for(DAO dao : daos) { + dao.close(NullTrans.singleton()); + } + } }