diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/WebfingerIssuerService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/WebfingerIssuerService.java
index d4f9d5ab3..283b9c982 100644
--- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/WebfingerIssuerService.java
+++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/WebfingerIssuerService.java
@@ -115,7 +115,7 @@ public class WebfingerIssuerService implements IssuerService {
throw new AuthenticationServiceException("Issuer was in blacklist: " + lr.issuer);
}
- return new IssuerServiceResponse(lr.issuer, lr.loginHint, null);
+ return new IssuerServiceResponse(lr.issuer, lr.loginHint, request.getParameter("target_link_uri"));
} catch (UncheckedExecutionException | ExecutionException e) {
logger.warn("Issue fetching issuer for user input: " + identifier + ": " + e.getMessage());
return null;
diff --git a/openid-connect-common/src/main/java/org/mitre/uma/service/ClaimsProcessingService.java b/openid-connect-common/src/main/java/org/mitre/uma/service/ClaimsProcessingService.java
index ff8752d9a..a598604bd 100644
--- a/openid-connect-common/src/main/java/org/mitre/uma/service/ClaimsProcessingService.java
+++ b/openid-connect-common/src/main/java/org/mitre/uma/service/ClaimsProcessingService.java
@@ -19,7 +19,6 @@ package org.mitre.uma.service;
import org.mitre.uma.model.ClaimProcessingResult;
import org.mitre.uma.model.PermissionTicket;
-import org.mitre.uma.model.PersistedClaimsToken;
import org.mitre.uma.model.ResourceSet;
/**
@@ -41,6 +40,6 @@ public interface ClaimsProcessingService {
* @param ticket the supplied claims to test
* @return the result of the claims processing action
*/
- public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket, PersistedClaimsToken pct);
+ public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket);
}
diff --git a/openid-connect-common/src/main/java/org/mitre/uma/service/PermissionService.java b/openid-connect-common/src/main/java/org/mitre/uma/service/PermissionService.java
index cd01b6c8f..04ed52939 100644
--- a/openid-connect-common/src/main/java/org/mitre/uma/service/PermissionService.java
+++ b/openid-connect-common/src/main/java/org/mitre/uma/service/PermissionService.java
@@ -55,4 +55,9 @@ public interface PermissionService {
*/
public PermissionTicket updateTicket(PermissionTicket ticket);
+ /**
+ * @param ticket
+ */
+ public void removeTicket(PermissionTicket ticket);
+
}
diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/views/claims_collection.jsp b/uma-server-webapp/src/main/webapp/WEB-INF/views/claims_collection.jsp
new file mode 100644
index 000000000..d2703c21e
--- /dev/null
+++ b/uma-server-webapp/src/main/webapp/WEB-INF/views/claims_collection.jsp
@@ -0,0 +1,75 @@
+<%@page import="org.springframework.http.HttpStatus"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%>
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
+<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
+<%@page import="org.springframework.security.oauth2.common.exceptions.OAuth2Exception"%>
+
+
+
+
+
+
+
+
+
The client
+
+
+
+
+
+
+
+
+ is requesting access to the resource set
+
+
+
+
+
+
+
+ .
+
+
+
This system requires that you identify yourself before the process can continue.
+
+
So far, you have provided the following claims:
+
+
+ - NONE
+
+
+ -
+ :
+ ()
+
+
+
+
+
+
Enter your email address to log in with OpenID Connect
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java b/uma-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
similarity index 100%
rename from uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
rename to uma-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java b/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java
index b58e1afaa..84a0881ec 100644
--- a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java
+++ b/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java
@@ -94,6 +94,14 @@ public class DefaultPermissionService implements PermissionService {
}
+ /* (non-Javadoc)
+ * @see org.mitre.uma.service.PermissionService#removeTicket(org.mitre.uma.model.PermissionTicket)
+ */
+ @Override
+ public void removeTicket(PermissionTicket ticket) {
+ repository.remove(ticket);
+ }
+
}
diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java b/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java
index 19695566a..ac505444f 100644
--- a/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java
+++ b/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java
@@ -23,7 +23,6 @@ import java.util.HashSet;
import org.mitre.uma.model.Claim;
import org.mitre.uma.model.ClaimProcessingResult;
import org.mitre.uma.model.PermissionTicket;
-import org.mitre.uma.model.PersistedClaimsToken;
import org.mitre.uma.model.Policy;
import org.mitre.uma.model.ResourceSet;
import org.mitre.uma.service.ClaimsProcessingService;
@@ -43,15 +42,10 @@ public class MatchAllClaimsOnAnyPolicy implements ClaimsProcessingService {
* @see org.mitre.uma.service.ClaimsProcessingService#claimsAreSatisfied(java.util.Collection, java.util.Collection)
*/
@Override
- public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket, PersistedClaimsToken pct) {
+ public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket) {
Collection allUnmatched = new HashSet<>();
- Collection claimsSupplied = new HashSet<>(ticket.getClaimsSupplied()); // copy the claims out of the ticket
- if (pct != null && pct.getClaimsSupplied() != null) {
- // add the claims from the PCT if available
- claimsSupplied.addAll(pct.getClaimsSupplied());
- }
for (Policy policy : rs.getPolicies()) {
- Collection unmatched = checkIndividualClaims(policy.getClaimsRequired(), claimsSupplied);
+ Collection unmatched = checkIndividualClaims(policy.getClaimsRequired(), ticket.getClaimsSupplied());
if (unmatched.isEmpty()) {
// we found something that's satisfied the claims, let's go with it!
return new ClaimProcessingResult(policy);
diff --git a/uma-server/src/main/java/org/mitre/uma/token/RequestingPartyTokenGranter.java b/uma-server/src/main/java/org/mitre/uma/token/RequestingPartyTokenGranter.java
index f8a16e884..8a34424c8 100644
--- a/uma-server/src/main/java/org/mitre/uma/token/RequestingPartyTokenGranter.java
+++ b/uma-server/src/main/java/org/mitre/uma/token/RequestingPartyTokenGranter.java
@@ -17,6 +17,7 @@
package org.mitre.uma.token;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -153,8 +154,15 @@ public class RequestingPartyTokenGranter extends AbstractTokenGranter {
throw new NotAuthorizedException();
} else {
// claims weren't empty or missing, we need to check against what we have
+
+ if (pct != null && pct.getClaimsSupplied() != null) {
+ // add the claims from the PCT if available
+ Collection claimsSupplied = new HashSet<>(ticket.getClaimsSupplied()); // copy the claims out of the ticket
+ claimsSupplied.addAll(pct.getClaimsSupplied());
+ ticket.setClaimsSupplied(claimsSupplied);
+ }
- ClaimProcessingResult result = claimsProcessingService.claimsAreSatisfied(rs, ticket, pct);
+ ClaimProcessingResult result = claimsProcessingService.claimsAreSatisfied(rs, ticket);
if (result.isSatisfied()) {
@@ -244,6 +252,9 @@ public class RequestingPartyTokenGranter extends AbstractTokenGranter {
tokenService.revokeAccessToken(incomingRpt);
}
+ // remove our ticket because it shouldn't be used again
+ permissionService.removeTicket(ticket);
+
// create a PCT
PersistedClaimsToken newPct = new PersistedClaimsToken();
newPct.setClientId(client.getClientId());
diff --git a/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java
index bc9e39ebe..7b638e956 100644
--- a/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java
+++ b/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java
@@ -19,6 +19,8 @@ package org.mitre.uma.web;
import java.util.Set;
+import javax.servlet.http.HttpSession;
+
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
@@ -26,6 +28,8 @@ import org.mitre.openid.connect.model.UserInfo;
import org.mitre.openid.connect.view.HttpCodeView;
import org.mitre.uma.model.Claim;
import org.mitre.uma.model.PermissionTicket;
+import org.mitre.uma.model.ResourceSet;
+import org.mitre.uma.service.ClaimsProcessingService;
import org.mitre.uma.service.PermissionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,7 +57,6 @@ import com.google.gson.JsonPrimitive;
*
*/
@Controller
-@PreAuthorize("hasRole('ROLE_EXTERNAL_USER')")
@RequestMapping("/" + ClaimsCollectionEndpoint.URL)
public class ClaimsCollectionEndpoint {
// Logger for this class
@@ -61,17 +64,26 @@ public class ClaimsCollectionEndpoint {
public static final String URL = "rqp_claims";
+ // variables for session storage
+ private static final String TICKET = URL + "-ticket";
+ private static final String CLIENT = URL + "-client";
+ private static final String REDIRECT_URI = URL + "-redirect_uri";
+ private static final String STATE = URL + "-state";
+
@Autowired
private ClientDetailsEntityService clientService;
@Autowired
private PermissionService permissionService;
+ @Autowired
+ private ClaimsProcessingService claimsProcessingService;
+
@RequestMapping(method = RequestMethod.GET)
- public String collectClaims(@RequestParam("client_id") String clientId, @RequestParam(value = "redirect_uri", required = false) String redirectUri,
+ public String startClaimsCollection(@RequestParam("client_id") String clientId, @RequestParam(value = "redirect_uri", required = false) String redirectUri,
@RequestParam("ticket") String ticketValue, @RequestParam(value = "state", required = false) String state,
- Model m, OIDCAuthenticationToken auth) {
+ Model m, OIDCAuthenticationToken auth, HttpSession session) {
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
@@ -79,42 +91,80 @@ public class ClaimsCollectionEndpoint {
PermissionTicket ticket = permissionService.getByTicket(ticketValue);
if (client == null || ticket == null) {
+ // couldn't find the client or the ticket, we bail here
logger.info("Client or ticket not found: " + clientId + " :: " + ticketValue);
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
return HttpCodeView.VIEWNAME;
}
-
+
+ // stash the client and ticket on the session and send the user to the claims endpoint
+ session.setAttribute(TICKET, ticket);
+ session.setAttribute(CLIENT, client);
+ session.setAttribute(REDIRECT_URI, redirectUri);
+
+ return "redirect:" + URL + "/collect";
+ }
+
+ @RequestMapping(value = "/collect", method = RequestMethod.GET)
+ public String collectClaims(Model m, OIDCAuthenticationToken auth, HttpSession session) {
+
+ ClientDetailsEntity client = (ClientDetailsEntity) session.getAttribute(CLIENT);
+ PermissionTicket ticket = (PermissionTicket) session.getAttribute(TICKET);
+
// we've got a client and ticket, let's attach the claims that we have from the token and userinfo
// subject
Set claimsSupplied = Sets.newHashSet(ticket.getClaimsSupplied());
- String issuer = auth.getIssuer();
- UserInfo userInfo = auth.getUserInfo();
-
- claimsSupplied.add(mkClaim(issuer, "sub", new JsonPrimitive(auth.getSub())));
- if (userInfo.getEmail() != null) {
- claimsSupplied.add(mkClaim(issuer, "email", new JsonPrimitive(userInfo.getEmail())));
- }
- if (userInfo.getEmailVerified() != null) {
- claimsSupplied.add(mkClaim(issuer, "email_verified", new JsonPrimitive(userInfo.getEmailVerified())));
- }
- if (userInfo.getPhoneNumber() != null) {
- claimsSupplied.add(mkClaim(issuer, "phone_number", new JsonPrimitive(auth.getUserInfo().getPhoneNumber())));
- }
- if (userInfo.getPhoneNumberVerified() != null) {
- claimsSupplied.add(mkClaim(issuer, "phone_number_verified", new JsonPrimitive(auth.getUserInfo().getPhoneNumberVerified())));
- }
- if (userInfo.getPreferredUsername() != null) {
- claimsSupplied.add(mkClaim(issuer, "preferred_username", new JsonPrimitive(auth.getUserInfo().getPreferredUsername())));
- }
- if (userInfo.getProfile() != null) {
- claimsSupplied.add(mkClaim(issuer, "profile", new JsonPrimitive(auth.getUserInfo().getProfile())));
- }
-
- ticket.setClaimsSupplied(claimsSupplied);
+ if (auth != null) {
- PermissionTicket updatedTicket = permissionService.updateTicket(ticket);
+ String issuer = auth.getIssuer();
+ UserInfo userInfo = auth.getUserInfo();
+
+ claimsSupplied.add(mkClaim(issuer, "sub", new JsonPrimitive(auth.getSub())));
+ if (userInfo.getEmail() != null) {
+ claimsSupplied.add(mkClaim(issuer, "email", new JsonPrimitive(userInfo.getEmail())));
+ }
+ if (userInfo.getEmailVerified() != null) {
+ claimsSupplied.add(mkClaim(issuer, "email_verified", new JsonPrimitive(userInfo.getEmailVerified())));
+ }
+ if (userInfo.getPhoneNumber() != null) {
+ claimsSupplied.add(mkClaim(issuer, "phone_number", new JsonPrimitive(auth.getUserInfo().getPhoneNumber())));
+ }
+ if (userInfo.getPhoneNumberVerified() != null) {
+ claimsSupplied.add(mkClaim(issuer, "phone_number_verified", new JsonPrimitive(auth.getUserInfo().getPhoneNumberVerified())));
+ }
+ if (userInfo.getPreferredUsername() != null) {
+ claimsSupplied.add(mkClaim(issuer, "preferred_username", new JsonPrimitive(auth.getUserInfo().getPreferredUsername())));
+ }
+ if (userInfo.getProfile() != null) {
+ claimsSupplied.add(mkClaim(issuer, "profile", new JsonPrimitive(auth.getUserInfo().getProfile())));
+ }
+
+ ticket.setClaimsSupplied(claimsSupplied);
+
+ ticket = permissionService.updateTicket(ticket);
+
+ session.setAttribute(TICKET, ticket);
+ }
+
+ ResourceSet resourceSet = ticket.getPermission().getResourceSet();
+
+ m.addAttribute("claims", ticket.getClaimsSupplied());
+ m.addAttribute("resourceSet", resourceSet);
+ m.addAttribute("client", client);
+ m.addAttribute("claimsResult", claimsProcessingService.claimsAreSatisfied(resourceSet, ticket));
+
+ return "claims_collection";
+ }
+
+ @RequestMapping(method = RequestMethod.POST)
+ public String returnToClient(Model m, OIDCAuthenticationToken auth, HttpSession session) {
+
+ ClientDetailsEntity client = (ClientDetailsEntity) session.getAttribute(CLIENT);
+ PermissionTicket ticket = (PermissionTicket) session.getAttribute(TICKET);
+ String redirectUri = (String) session.getAttribute(REDIRECT_URI);
+ String state = (String) session.getAttribute(STATE);
if (Strings.isNullOrEmpty(redirectUri)) {
if (client.getClaimsRedirectUris().size() == 1) {
@@ -131,7 +181,7 @@ public class ClaimsCollectionEndpoint {
UriComponentsBuilder template = UriComponentsBuilder.fromUriString(redirectUri);
template.queryParam("authorization_state", "claims_submitted");
- template.queryParam("ticket", updatedTicket.getTicket());
+ template.queryParam("ticket", ticket.getTicket());
if (!Strings.isNullOrEmpty(state)) {
template.queryParam("state", state);
}
diff --git a/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java
index ab59d660a..e20335ea4 100644
--- a/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java
+++ b/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java
@@ -43,7 +43,7 @@ public class UmaDiscoveryEndpoint {
@Autowired
private ConfigurationPropertiesBean config;
- @RequestMapping(".well-known/multiparty-delegation-configuration")
+ @RequestMapping(".well-known/uma2-configuration")
public String umaConfiguration(Model model) {
Map m = new HashMap<>();