Added PCT support, doesn't return from token endpoint yet
parent
fcff1be114
commit
f8372666e6
|
@ -0,0 +1,148 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2016 The MITRE Corporation
|
||||
* and the MIT Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "persisted_claims_token")
|
||||
@NamedQueries ({
|
||||
@NamedQuery(name = PersistedClaimsToken.QUERY_BY_VALUE, query = "select p from PersistedClaimsToken p where p.value = :" + PersistedClaimsToken.PARAM_VALUE),
|
||||
})
|
||||
public class PersistedClaimsToken {
|
||||
|
||||
public static final String QUERY_BY_VALUE = "PersistedClaimsToken.queryByValue";
|
||||
|
||||
public static final String PARAM_VALUE = "value";
|
||||
|
||||
private Long id;
|
||||
private String clientId;
|
||||
private Date expiration;
|
||||
private Collection<Claim> claimsSupplied;
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientId
|
||||
*/
|
||||
@Basic
|
||||
@Column(name = "client_id")
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId the clientId to set
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expiration
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "expiration")
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expiration the expiration to set
|
||||
*/
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the claimsSupplied
|
||||
*/
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinTable(
|
||||
name = "claim_to_permission_ticket",
|
||||
joinColumns = @JoinColumn(name = "permission_ticket_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "claim_id")
|
||||
)
|
||||
public Collection<Claim> getClaimsSupplied() {
|
||||
return claimsSupplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param claimsSupplied the claimsSupplied to set
|
||||
*/
|
||||
public void setClaimsSupplied(Collection<Claim> claimsSupplied) {
|
||||
this.claimsSupplied = claimsSupplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
@Basic
|
||||
@Column(name = "token_value")
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value to set
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2016 The MITRE Corporation
|
||||
* and the MIT Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.repository;
|
||||
|
||||
import org.mitre.uma.model.PersistedClaimsToken;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public interface PersistedClaimsTokenRepository {
|
||||
|
||||
/**
|
||||
* @param pctValue
|
||||
* @return
|
||||
*/
|
||||
PersistedClaimsToken getByValue(String pctValue);
|
||||
|
||||
/**
|
||||
* @param pct
|
||||
* @return
|
||||
*/
|
||||
PersistedClaimsToken save(PersistedClaimsToken pct);
|
||||
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ 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;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,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);
|
||||
public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket, PersistedClaimsToken pct);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.mitre.uma.service;
|
|||
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.PersistedClaimsToken;
|
||||
import org.mitre.uma.model.Policy;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
|
||||
|
@ -36,4 +37,12 @@ public interface UmaTokenService {
|
|||
*/
|
||||
public OAuth2AccessTokenEntity createRequestingPartyToken(OAuth2Authentication o2auth, PermissionTicket ticket, Policy policy);
|
||||
|
||||
/**
|
||||
* @param pctValue
|
||||
* @return
|
||||
*/
|
||||
public PersistedClaimsToken getPersistedClaimsTokenByValue(String pctValue);
|
||||
|
||||
public PersistedClaimsToken savePersistedClaimsToken(PersistedClaimsToken pct);
|
||||
|
||||
}
|
||||
|
|
|
@ -330,6 +330,17 @@ CREATE TABLE IF NOT EXISTS claim_to_permission_ticket (
|
|||
claim_id BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS claim_to_pct (
|
||||
pct_id BIGINT NOT NULL,
|
||||
claim_id BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS persisted_claims_token (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
|
||||
client_id VARCHAR(256),
|
||||
token_value VARCHAR(2048)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS policy (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
|
||||
name VARCHAR(1024),
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2016 The MITRE Corporation
|
||||
* and the MIT Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.repository.impl;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.mitre.uma.model.PersistedClaimsToken;
|
||||
import org.mitre.uma.repository.PersistedClaimsTokenRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
@Repository("persistedClaimsTokenRepository")
|
||||
public class JpaPersistedClaimsTokenRepository implements PersistedClaimsTokenRepository {
|
||||
|
||||
@PersistenceContext(unitName="defaultPersistenceUnit")
|
||||
private EntityManager em;
|
||||
private static Logger logger = LoggerFactory.getLogger(JpaPersistedClaimsTokenRepository.class);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.uma.repository.PersistedClaimsTokenRepository#getPersistedClaimsTokenByValue(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public PersistedClaimsToken getByValue(String pctValue) {
|
||||
TypedQuery<PersistedClaimsToken> query = em.createNamedQuery(PersistedClaimsToken.QUERY_BY_VALUE, PersistedClaimsToken.class);
|
||||
query.setParameter(PersistedClaimsToken.PARAM_VALUE, pctValue);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.uma.repository.PersistedClaimsTokenRepository#savePersistedClaimsToken(org.mitre.uma.model.PersistedClaimsToken)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(value="defaultTransactionManager")
|
||||
public PersistedClaimsToken save(PersistedClaimsToken pct) {
|
||||
return JpaUtil.saveOrUpdate(pct.getId(), em, pct);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,9 @@ import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
|||
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.PersistedClaimsToken;
|
||||
import org.mitre.uma.model.Policy;
|
||||
import org.mitre.uma.repository.PersistedClaimsTokenRepository;
|
||||
import org.mitre.uma.service.UmaTokenService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
|
@ -66,6 +68,9 @@ public class DefaultUmaTokenService implements UmaTokenService {
|
|||
|
||||
@Autowired
|
||||
private JWTSigningAndValidationService jwtService;
|
||||
|
||||
@Autowired
|
||||
private PersistedClaimsTokenRepository pctRepository;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -118,4 +123,23 @@ public class DefaultUmaTokenService implements UmaTokenService {
|
|||
return token;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.uma.service.UmaTokenService#getPersistedClaimsTokenByValue(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public PersistedClaimsToken getPersistedClaimsTokenByValue(String pctValue) {
|
||||
return pctRepository.getByValue(pctValue);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.uma.service.UmaTokenService#savePersistedClaimsToken(org.mitre.uma.model.PersistedClaimsToken)
|
||||
*/
|
||||
@Override
|
||||
public PersistedClaimsToken savePersistedClaimsToken(PersistedClaimsToken pct) {
|
||||
return pctRepository.save(pct);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ 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;
|
||||
|
@ -42,10 +43,15 @@ 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) {
|
||||
public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket, PersistedClaimsToken pct) {
|
||||
Collection<Claim> allUnmatched = new HashSet<>();
|
||||
Collection<Claim> 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<Claim> unmatched = checkIndividualClaims(policy.getClaimsRequired(), ticket.getClaimsSupplied());
|
||||
Collection<Claim> unmatched = checkIndividualClaims(policy.getClaimsRequired(), claimsSupplied);
|
||||
if (unmatched.isEmpty()) {
|
||||
// we found something that's satisfied the claims, let's go with it!
|
||||
return new ClaimProcessingResult(policy);
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.mitre.uma.model.Claim;
|
|||
import org.mitre.uma.model.ClaimProcessingResult;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.PersistedClaimsToken;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.service.ClaimsProcessingService;
|
||||
import org.mitre.uma.service.PermissionService;
|
||||
|
@ -134,6 +135,12 @@ public class RequestingPartyTokenGranter extends AbstractTokenGranter {
|
|||
if (!Strings.isNullOrEmpty(rptValue)) {
|
||||
incomingRpt = tokenService.readAccessToken(rptValue);
|
||||
}
|
||||
|
||||
String pctValue = tokenRequest.getRequestParameters().get("pct");
|
||||
PersistedClaimsToken pct = null;
|
||||
if (!Strings.isNullOrEmpty(pctValue)) {
|
||||
pct = umaTokenService.getPersistedClaimsTokenByValue(pctValue);
|
||||
}
|
||||
|
||||
if (ticket != null) {
|
||||
// found the ticket, see if it's any good
|
||||
|
@ -147,7 +154,7 @@ public class RequestingPartyTokenGranter extends AbstractTokenGranter {
|
|||
} else {
|
||||
// claims weren't empty or missing, we need to check against what we have
|
||||
|
||||
ClaimProcessingResult result = claimsProcessingService.claimsAreSatisfied(rs, ticket);
|
||||
ClaimProcessingResult result = claimsProcessingService.claimsAreSatisfied(rs, ticket, pct);
|
||||
|
||||
|
||||
if (result.isSatisfied()) {
|
||||
|
@ -236,7 +243,20 @@ public class RequestingPartyTokenGranter extends AbstractTokenGranter {
|
|||
if (incomingRpt != null) {
|
||||
tokenService.revokeAccessToken(incomingRpt);
|
||||
}
|
||||
|
||||
// create a PCT
|
||||
PersistedClaimsToken newPct = new PersistedClaimsToken();
|
||||
newPct.setClientId(client.getClientId());
|
||||
newPct.setExpiration(null); // TODO: we'll make these not expire for now, should be configurable per-client like other token lifetimes
|
||||
newPct.setValue(UUID.randomUUID().toString()); // make a random value
|
||||
HashSet<Claim> claimsSupplied = new HashSet<>();
|
||||
claimsSupplied.addAll(ticket.getClaimsSupplied());
|
||||
if (pct != null && pct.getClaimsSupplied() != null) {
|
||||
claimsSupplied.addAll(pct.getClaimsSupplied());
|
||||
}
|
||||
newPct.setClaimsSupplied(claimsSupplied);
|
||||
|
||||
// TODO: figure out how to return the PCT in the token response
|
||||
return token;
|
||||
} else {
|
||||
|
||||
|
|
Loading…
Reference in New Issue