diff --git a/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetail.java b/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetail.java new file mode 100644 index 000000000..2a7218841 --- /dev/null +++ b/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetail.java @@ -0,0 +1,44 @@ +package org.gluu.oxauth.model.authzdetails; + +import org.json.JSONObject; + +/** + * @author Yuriy Z + */ +public class AuthzDetail { + + private final JSONObject jsonObject; + private String uiRepresentation; + + public AuthzDetail(String json) { + this(new JSONObject(json)); + } + + public AuthzDetail(JSONObject jsonObject) { + this.jsonObject = jsonObject; + } + + public JSONObject getJsonObject() { + return jsonObject; + } + + public String getType() { + return jsonObject.optString("type"); + } + + public String getUiRepresentation() { + return uiRepresentation; + } + + public void setUiRepresentation(String uiRepresentation) { + this.uiRepresentation = uiRepresentation; + } + + @Override + public String toString() { + return "AuthzDetail{" + + "jsonObject=" + jsonObject + + "uiRepresentation=" + uiRepresentation + + '}'; + } +} diff --git a/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetails.java b/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetails.java new file mode 100644 index 000000000..81742591e --- /dev/null +++ b/Model/src/main/java/org/gluu/oxauth/model/authzdetails/AuthzDetails.java @@ -0,0 +1,105 @@ +package org.gluu.oxauth.model.authzdetails; + +import org.apache.commons.lang3.StringUtils; +import org.json.JSONArray; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Yuriy Z + */ +public class AuthzDetails { + + private final List details; + + public AuthzDetails(List details) { + this.details = details; + } + + public AuthzDetails() { + this(new ArrayList<>()); + } + + public static AuthzDetails of(String jsonArray) { + return of(new JSONArray(jsonArray)); + } + + public static AuthzDetails ofSilently(String jsonArray) { + try { + return of(new JSONArray(jsonArray)); + } catch (Exception e) { + return null; + } + } + + public static AuthzDetails of(JSONArray jsonArray) { + AuthzDetails result = new AuthzDetails(); + for (int i = 0; i < jsonArray.length(); i++) { + result.details.add(new AuthzDetail(jsonArray.getJSONObject(i))); + } + return result; + } + + public static boolean similar(String authorizationDetails1, String authorizationDetails2) { + if (StringUtils.equals(authorizationDetails1, authorizationDetails2)) { + return true; + } + if (authorizationDetails1 == null || authorizationDetails2 == null) { + return false; + } + JSONArray array1 = new JSONArray(authorizationDetails1); + JSONArray array2 = new JSONArray(authorizationDetails2); + return array1.similar(array2); + } + + public static String simpleMerge(String authorizationDetails1, String authorizationDetails2) { + final AuthzDetails details1 = AuthzDetails.of(authorizationDetails1); + final AuthzDetails details2 = AuthzDetails.of(authorizationDetails2); + details1.getDetails().addAll(details2.getDetails()); + return details1.asJsonArray().toString(); + } + + public JSONArray asJsonArray() { + JSONArray array = new JSONArray(); + array.putAll(details.stream().map(AuthzDetail::getJsonObject).collect(Collectors.toList())); + return array; + } + + public String asJsonString() { + return asJsonArray().toString(); + } + + public boolean similar(String authorizationDetails) { + if (StringUtils.isBlank(authorizationDetails)) { + return false; + } + return asJsonArray().similar(new JSONArray(authorizationDetails)); + } + + public List getDetails() { + return details; + } + + public Set getTypes() { + Set result = new HashSet<>(); + for (AuthzDetail d : details) { + result.add(d.getType()); + } + return result; + } + + public static boolean isEmpty(AuthzDetails authzDetails) { + return authzDetails == null || authzDetails.getDetails() == null || authzDetails.getDetails().isEmpty(); + } + + @Override + public String toString() { + return "AuthzDetails{" + + "details=" + details + + '}'; + } +} diff --git a/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequest.java b/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequest.java new file mode 100644 index 000000000..c6231c532 --- /dev/null +++ b/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequest.java @@ -0,0 +1,472 @@ +package org.gluu.oxauth.authorize.ws.rs; + +import com.google.common.collect.Sets; +import org.gluu.oxauth.model.audit.OAuth2AuditLog; +import org.gluu.oxauth.model.authorize.JwtAuthorizationRequest; +import org.gluu.oxauth.model.authzdetails.AuthzDetails; +import org.gluu.oxauth.model.common.Prompt; +import org.gluu.oxauth.model.common.ResponseMode; +import org.gluu.oxauth.model.common.ResponseType; +import org.gluu.oxauth.model.registration.Client; +import org.gluu.oxauth.model.session.AuthorizationChallengeSession; +import org.gluu.oxauth.model.util.Util; +import org.gluu.oxauth.service.RedirectUriResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.SecurityContext; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.gluu.oxauth.model.util.StringUtils.implode; + +/** + * @author Yuriy Z + */ +public class AuthzRequest { + + private static final Logger log = LoggerFactory.getLogger(AuthzRequest.class); + + private String scope; + private String responseType; + private String clientId; + private String redirectUri; + private String state; + private String responseMode; + private String nonce; + private String display; + private String prompt; + private Integer maxAge; + private String uiLocales; + private String idTokenHint; + private String loginHint; + private String acrValues; + private String amrValues; + private String request; + private String requestUri; + private String sessionId; + private String originHeaders; + private String codeChallenge; + private String codeChallengeMethod; + private String customResponseHeaders; + private String claims; + private String authReqId; + private String dpopJkt; + private String authzDetailsString; + private AuthzDetails authzDetails; + private String httpMethod; + private String authorizationChallengeSession; + private AuthorizationChallengeSession authorizationChallengeSessionObject; + private boolean useAuthorizationChallengeSession; + private HttpServletRequest httpRequest; + private HttpServletResponse httpResponse; + private SecurityContext securityContext; + private Map customParameters; + private JwtAuthorizationRequest jwtRequest; + private RedirectUriResponse redirectUriResponse; + private Client client; + private OAuth2AuditLog auditLog; + private boolean promptFromJwt; + + public String getAuthzDetailsString() { + return authzDetailsString; + } + + public void setAuthzDetailsString(String authzDetailsString) { + this.authzDetailsString = authzDetailsString; + } + + public AuthzDetails getAuthzDetails() { + return authzDetails; + } + + public void setAuthzDetails(AuthzDetails authzDetails) { + this.authzDetails = authzDetails; + } + + public String getDpopJkt() { + return dpopJkt; + } + + public void setDpopJkt(String dpopJkt) { + this.dpopJkt = dpopJkt; + } + + public AuthorizationChallengeSession getAuthorizationChallengeSessionObject() { + return authorizationChallengeSessionObject; + } + + public void setAuthorizationChallengeSessionObject(AuthorizationChallengeSession authorizationChallengeSessionObject) { + this.authorizationChallengeSessionObject = authorizationChallengeSessionObject; + } + + public boolean isUseAuthorizationChallengeSession() { + return useAuthorizationChallengeSession; + } + + public void setUseAuthorizationChallengeSession(boolean useAuthorizationChallengeSession) { + this.useAuthorizationChallengeSession = useAuthorizationChallengeSession; + } + + public String getAuthorizationChallengeSession() { + return authorizationChallengeSession; + } + + public void setAuthorizationChallengeSession(String authorizationChallengeSession) { + this.authorizationChallengeSession = authorizationChallengeSession; + } + + public boolean isPromptFromJwt() { + return promptFromJwt; + } + + public void setPromptFromJwt(boolean promptFromJwt) { + this.promptFromJwt = promptFromJwt; + } + + public OAuth2AuditLog getAuditLog() { + return auditLog; + } + + public void setAuditLog(OAuth2AuditLog auditLog) { + this.auditLog = auditLog; + } + + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + public RedirectUriResponse getRedirectUriResponse() { + return redirectUriResponse; + } + + public void setRedirectUriResponse(RedirectUriResponse redirectUriResponse) { + this.redirectUriResponse = redirectUriResponse; + } + + public JwtAuthorizationRequest getJwtRequest() { + return jwtRequest; + } + + public void setJwtRequest(JwtAuthorizationRequest jwtRequest) { + this.jwtRequest = jwtRequest; + } + + public Map getCustomParameters() { + if (customParameters == null) { + customParameters = new HashMap<>(); + } + return customParameters; + } + + public void setCustomParameters(Map customParameters) { + this.customParameters = customParameters; + } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public List getResponseTypeList() { + return ResponseType.fromString(responseType, " "); + } + + public String getResponseType() { + return responseType; + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getRedirectUri() { + return redirectUri; + } + + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getResponseMode() { + return responseMode; + } + + public ResponseMode getResponseModeEnum() { + return ResponseMode.getByValue(responseMode); + } + + public void setResponseMode(String responseMode) { + this.responseMode = responseMode; + } + + public String getNonce() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public List getPromptList() { + return Prompt.fromString(prompt, " "); + } + + public void setPromptList(List prompts) { + setPrompt(implode(Sets.newHashSet(prompts), " ")); + } + + public void addPrompt(Prompt prompt) { + final List prompts = getPromptList(); + prompts.add(prompt); + log.trace("Added prompt '{}'", prompt); + setPromptList(prompts); + } + + public void removePrompt(Prompt prompt) { + final List prompts = getPromptList(); + prompts.remove(prompt); + log.trace("Removed prompt '{}'", prompt); + setPromptList(prompts); + } + + public String getPrompt() { + return prompt; + } + + public void setPrompt(String prompt) { + this.prompt = prompt; + log.trace("Set prompt to '{}'", prompt); + } + + public Integer getMaxAge() { + return maxAge; + } + + public void setMaxAge(Integer maxAge) { + this.maxAge = maxAge; + } + + public String getUiLocales() { + return uiLocales; + } + + public List getUiLocalesList() { + return Util.splittedStringAsList(uiLocales, " "); + } + + public void setUiLocales(String uiLocales) { + this.uiLocales = uiLocales; + } + + public String getIdTokenHint() { + return idTokenHint; + } + + public void setIdTokenHint(String idTokenHint) { + this.idTokenHint = idTokenHint; + } + + public String getLoginHint() { + return loginHint; + } + + public void setLoginHint(String loginHint) { + this.loginHint = loginHint; + } + + public String getAcrValues() { + return acrValues; + } + + public List getAcrValuesList() { + return Util.splittedStringAsList(acrValues, " "); + } + + public void setAcrValues(String acrValues) { + this.acrValues = acrValues; + } + + public String getAmrValues() { + return amrValues; + } + + public void setAmrValues(String amrValues) { + this.amrValues = amrValues; + } + + public String getRequest() { + return request; + } + + public void setRequest(String request) { + this.request = request; + } + + public String getRequestUri() { + return requestUri; + } + + public void setRequestUri(String requestUri) { + this.requestUri = requestUri; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public String getOriginHeaders() { + return originHeaders; + } + + public void setOriginHeaders(String originHeaders) { + this.originHeaders = originHeaders; + } + + public String getCodeChallenge() { + return codeChallenge; + } + + public void setCodeChallenge(String codeChallenge) { + this.codeChallenge = codeChallenge; + } + + public String getCodeChallengeMethod() { + return codeChallengeMethod; + } + + public void setCodeChallengeMethod(String codeChallengeMethod) { + this.codeChallengeMethod = codeChallengeMethod; + } + + public String getCustomResponseHeaders() { + return customResponseHeaders; + } + + public void setCustomResponseHeaders(String customResponseHeaders) { + this.customResponseHeaders = customResponseHeaders; + } + + public String getClaims() { + return claims; + } + + public void setClaims(String claims) { + this.claims = claims; + } + + public String getAuthReqId() { + return authReqId; + } + + public void setAuthReqId(String authReqId) { + this.authReqId = authReqId; + } + + public HttpServletRequest getHttpRequest() { + return httpRequest; + } + + public void setHttpRequest(HttpServletRequest httpRequest) { + this.httpRequest = httpRequest; + } + + public HttpServletResponse getHttpResponse() { + return httpResponse; + } + + public void setHttpResponse(HttpServletResponse httpResponse) { + this.httpResponse = httpResponse; + } + + public SecurityContext getSecurityContext() { + return securityContext; + } + + public void setSecurityContext(SecurityContext securityContext) { + this.securityContext = securityContext; + } + + @Override + public String toString() { + return "AuthzRequest{" + + "scope='" + scope + '\'' + + ", responseType='" + responseType + '\'' + + ", clientId='" + clientId + '\'' + + ", redirectUri='" + redirectUri + '\'' + + ", state='" + state + '\'' + + ", responseMode='" + responseMode + '\'' + + ", nonce='" + nonce + '\'' + + ", display='" + display + '\'' + + ", prompt='" + prompt + '\'' + + ", maxAge=" + maxAge + + ", uiLocales='" + uiLocales + '\'' + + ", idTokenHint='" + idTokenHint + '\'' + + ", loginHint='" + loginHint + '\'' + + ", acrValues='" + acrValues + '\'' + + ", authorizationChallengeSession='" + authorizationChallengeSession + '\'' + + ", amrValues='" + amrValues + '\'' + + ", request='" + request + '\'' + + ", requestUri='" + requestUri + '\'' + + ", authzDetailsString='" + authzDetailsString + '\'' + + ", authzDetails='" + authzDetails + '\'' + + ", sessionId='" + sessionId + '\'' + + ", originHeaders='" + originHeaders + '\'' + + ", codeChallenge='" + codeChallenge + '\'' + + ", codeChallengeMethod='" + codeChallengeMethod + '\'' + + ", customResponseHeaders='" + customResponseHeaders + '\'' + + ", customParameters='" + customParameters+ '\'' + + ", claims='" + claims + '\'' + + ", authReqId='" + authReqId + '\'' + + ", httpRequest=" + httpRequest + + ", httpResponse=" + httpResponse + + ", securityContext=" + securityContext + + '}'; + } +} diff --git a/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequestService.java b/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequestService.java new file mode 100644 index 000000000..67ee1ea5e --- /dev/null +++ b/Server/src/main/java/org/gluu/oxauth/authorize/ws/rs/AuthzRequestService.java @@ -0,0 +1,37 @@ +package org.gluu.oxauth.authorize.ws.rs; + +import org.gluu.oxauth.model.audit.Action; +import org.gluu.oxauth.model.audit.OAuth2AuditLog; +import org.gluu.oxauth.util.ServerUtil; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; +import javax.ws.rs.WebApplicationException; + +/** + * @author Yuriy Z + */ +@RequestScoped +@Named +public class AuthzRequestService { + + public static boolean canLogWebApplicationException(WebApplicationException e) { + if (e == null || e.getResponse() == null) { + return false; + } + final int status = e.getResponse().getStatus(); + return status != 302; + } + + public void createOauth2AuditLog(AuthzRequest authzRequest) { + createOauth2AuditLog(authzRequest, Action.USER_AUTHORIZATION); + } + + public void createOauth2AuditLog(AuthzRequest authzRequest, Action action) { + OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(authzRequest.getHttpRequest()), action); + oAuth2AuditLog.setClientId(authzRequest.getClientId()); + oAuth2AuditLog.setScope(authzRequest.getScope()); + + authzRequest.setAuditLog(oAuth2AuditLog); + } +}