First stages of getting the graylist portion to work. Currently no mechanism for telling the system NOT to remember your decision; that will come later. All approvals will be automatically stored with this code.
parent
db415bfa2b
commit
845976b8ac
|
@ -19,6 +19,7 @@ import java.util.Date;
|
|||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
|
@ -162,6 +163,10 @@ public class ApprovedSite {
|
|||
* @return the allowedScopes
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="allowed_scopes",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
public Set<String> getAllowedScopes() {
|
||||
return allowedScopes;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
create table allowed_scopes(
|
||||
owner_id VARCHAR(256),
|
||||
allowedScopes VARCHAR(256)
|
||||
);
|
|
@ -76,7 +76,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
public Collection<ApprovedSite> getByUserInfo(UserInfo userInfo) {
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(
|
||||
"ApprovedSite.getByUserInfo", ApprovedSite.class);
|
||||
query.setParameter("approvedSiteUserInfo", userInfo.getUserId());
|
||||
query.setParameter("approvedSiteUserInfo", userInfo);
|
||||
|
||||
List<ApprovedSite> found = query.getResultList();
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.persistence.TypedQuery;
|
|||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -88,8 +89,7 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
public WhitelistedSite getByClientDetails(ClientDetails client) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByClientDetails", WhitelistedSite.class);
|
||||
query.setParameter("clientDetails", client);
|
||||
|
||||
return query.getSingleResult();
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,7 +17,9 @@ package org.mitre.openid.connect.token;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.openid.connect.model.ApprovedSite;
|
||||
import org.mitre.openid.connect.model.DefaultUserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
|
@ -31,6 +33,9 @@ import org.springframework.security.oauth2.provider.ClientDetails;
|
|||
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Custom User Approval Handler implementation which uses a concept of a whitelist,
|
||||
* blacklist, and greylist.
|
||||
|
@ -75,19 +80,22 @@ public class JdbcUserApprovalHandler implements UserApprovalHandler {
|
|||
@Override
|
||||
public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
|
||||
|
||||
//Check database to see if the user identified by the userAuthentication has stored an approval decision
|
||||
//First, check database to see if the user identified by the userAuthentication has stored an approval decision
|
||||
|
||||
String userId = userAuthentication.getName();
|
||||
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
|
||||
|
||||
//lookup ApprovedSites by userId
|
||||
DefaultUserInfo user = (DefaultUserInfo)userInfoService.getByUserId(userId);
|
||||
|
||||
//lookup ApprovedSites by userId
|
||||
Collection<ApprovedSite> approvedSites = approvedSiteService.getByUserInfo(user);
|
||||
|
||||
for (ApprovedSite ap : approvedSites) {
|
||||
if (ap.getClientDetails().getClientId() == client.getClientId()) {
|
||||
//TODO need to test more than just id
|
||||
if (sitesMatch(ap, authorizationRequest, user)) {
|
||||
|
||||
//We have a match; update the access date on the AP entry and return true.
|
||||
ap.setAccessDate(new Date());
|
||||
approvedSiteService.save(ap);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,15 +115,57 @@ public class JdbcUserApprovalHandler implements UserApprovalHandler {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (authorizationRequest.isApproved() && !authorizationRequest.getApprovalParameters().isEmpty()) {
|
||||
boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval"));
|
||||
|
||||
if (approved && !authorizationRequest.getApprovalParameters().isEmpty()) {
|
||||
|
||||
//TODO: check approval parameters to see if we should store this request or not
|
||||
|
||||
//Make a new AP
|
||||
ApprovedSite newAP = new ApprovedSite();
|
||||
newAP.setAccessDate(new Date());
|
||||
//Set<String> allowedScopes = authorizationRequest.getApprovalParameters().get("scope");
|
||||
//newAP.setAllowedScopes(allowedScopes);
|
||||
String scopes = authorizationRequest.getAuthorizationParameters().get("scope");
|
||||
Set<String> allowedScopes = Sets.newHashSet(Splitter.on(" ").split(scopes));
|
||||
newAP.setAllowedScopes(allowedScopes);
|
||||
newAP.setClientDetails((ClientDetailsEntity)client);
|
||||
newAP.setUserInfo((DefaultUserInfo)user);
|
||||
newAP.setCreationDate(new Date());
|
||||
approvedSiteService.save(newAP);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given ApprovedSite entry matches the information about the current request.
|
||||
*
|
||||
* @param ap the ApprovedSite to compare
|
||||
* @param authReq the AuthorizationRequest for this requst
|
||||
* @param user the User making the request
|
||||
* @return true if everything matches, false otherwise
|
||||
*/
|
||||
private boolean sitesMatch(ApprovedSite ap, AuthorizationRequest authReq, DefaultUserInfo user) {
|
||||
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(authReq.getClientId());
|
||||
|
||||
String scopes = authReq.getAuthorizationParameters().get("scope");
|
||||
Set<String> allowedScopes = Sets.newHashSet(Splitter.on(" ").split(scopes));
|
||||
|
||||
if (!(ap.getClientDetails().getClientId()).equalsIgnoreCase(client.getClientId())) {
|
||||
return false;
|
||||
}
|
||||
if (!(ap.getUserInfo().getUserId()).equalsIgnoreCase(user.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
for (String scope : allowedScopes) {
|
||||
if (!ap.getAllowedScopes().contains(scope)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
client-details-service-ref="defaultOAuth2ClientDetailsEntityService"
|
||||
authorization-request-factory-ref="authorizationRequestFactory"
|
||||
token-services-ref="defaultOAuth2ProviderTokenService"
|
||||
user-approval-handler-ref="userApprovalHandler"
|
||||
user-approval-handler-ref="jdbcUserApprovalHandler"
|
||||
authorization-endpoint-url="/authorize"
|
||||
token-endpoint-url="/token">
|
||||
|
||||
|
@ -82,8 +82,7 @@
|
|||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler" id="userApprovalHandler">
|
||||
<property name="tokenServices" ref="defaultOAuth2ProviderTokenService" />
|
||||
<bean class="org.mitre.openid.connect.token.JdbcUserApprovalHandler" id="jdbcUserApprovalHandler">
|
||||
</bean>
|
||||
|
||||
<bean id="authCodeServices" class="org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices" />
|
||||
|
|
|
@ -62,16 +62,16 @@
|
|||
<div class="span4">
|
||||
<fieldset style="text-align:left" class="well">
|
||||
<legend style="margin-bottom: 0;">Access to:</legend>
|
||||
<label for="option1"></label>
|
||||
<input type="checkbox" name="option1" id="option1" checked="checked"> basic profile information
|
||||
<label for="option2"></label>
|
||||
<input type="checkbox" name="option1" id="option2" checked="checked"> email address
|
||||
<label for="option3"></label>
|
||||
<input type="checkbox" name="option3" id="option3" checked="checked"> address
|
||||
<label for="option4"></label>
|
||||
<input type="checkbox" name="option4" id="option4" checked="checked"> phone number
|
||||
<label for="option5"></label>
|
||||
<input type="checkbox" name="option5" id="option5" checked="checked"> offline access
|
||||
|
||||
<input type="checkbox" name="scope_profile" id="scope_profile" value="true" checked="checked"><label for="scope_profile">basic profile information</label>
|
||||
|
||||
<input type="checkbox" name="scope_email" id="scope_email" value="true" checked="checked"><label for="scope_email">email address</label>
|
||||
|
||||
<input type="checkbox" name="scope_address" id="scope_address" value="true" checked="checked"><label for="scope_address">address</label>
|
||||
|
||||
<input type="checkbox" name="scope_phone" id="scope_phone" value="true" checked="checked"><label for="scope_phone">phone number</label>
|
||||
|
||||
<input type="checkbox" name="scope_offline" id="scope_offline" value="true" checked="checked"><label for="scope_offline">offline access</label>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue