Implementing user approval handler; made some modifications to ApprovedSite and WhitelistedSite models, repositories, and service layers.
parent
7c33e19950
commit
4e10fce7ef
|
@ -47,7 +47,7 @@ public class ApprovedSite {
|
|||
private Long id;
|
||||
|
||||
// which user made the approval
|
||||
private String userInfo;
|
||||
private UserInfo userInfo;
|
||||
|
||||
// which OAuth2 client is this tied to
|
||||
private ClientDetailsEntity clientDetails;
|
||||
|
@ -65,6 +65,9 @@ public class ApprovedSite {
|
|||
// this should include all information for what data to access
|
||||
private Set<String> allowedScopes;
|
||||
|
||||
// If this AP is a WS, link to the WS
|
||||
private WhitelistedSite whitelistedSite;
|
||||
|
||||
// TODO: should we store the OAuth2 tokens and IdTokens here?
|
||||
|
||||
/**
|
||||
|
@ -93,15 +96,16 @@ public class ApprovedSite {
|
|||
/**
|
||||
* @return the userInfo
|
||||
*/
|
||||
@Basic
|
||||
public String getUserInfo() {
|
||||
@ManyToOne
|
||||
@JoinColumn(name="userinfo_id")
|
||||
public UserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userInfo the userInfo to set
|
||||
*/
|
||||
public void setUserInfo(String userInfo) {
|
||||
public void setUserInfo(UserInfo userInfo) {
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
|
||||
|
@ -183,7 +187,25 @@ public class ApprovedSite {
|
|||
public void setTimeoutDate(Date timeoutDate) {
|
||||
this.timeoutDate = timeoutDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Does this AP entry correspond to a WS?
|
||||
* @return
|
||||
*/
|
||||
@Basic
|
||||
public Boolean getIsWhitelisted() {
|
||||
return (whitelistedSite != null);
|
||||
}
|
||||
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="whitelistedsite_id")
|
||||
public WhitelistedSite getWhitelistedSite() {
|
||||
return whitelistedSite;
|
||||
}
|
||||
|
||||
public void setWhitelistedSite(WhitelistedSite whitelistedSite) {
|
||||
this.whitelistedSite = whitelistedSite;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.mitre.openid.connect.model;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
|
@ -35,22 +34,24 @@ import org.mitre.oauth2.model.ClientDetailsEntity;
|
|||
/**
|
||||
* Indicator that login to a site should be automatically granted
|
||||
* without user interaction.
|
||||
* @author jricher
|
||||
* @author jricher, aanganes
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="whitelistedsite")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w")
|
||||
@NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"),
|
||||
@NamedQuery(name = "WhitelistedSite.getByClientDetails", query = "select w from WhitelistedSite w where w.clientDetails = :clientDetails"),
|
||||
@NamedQuery(name = "WhitelistedSite.getByUserInfo", query = "select w from WhitelistedSite w where w.creator = :userInfo")
|
||||
})
|
||||
public class WhitelistedSite {
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
// who added this site to the whitelist (should be an admin)
|
||||
private String userInfo;
|
||||
|
||||
// Reference to the admin user who created this entry
|
||||
private UserInfo creator;
|
||||
|
||||
// which OAuth2 client is this tied to
|
||||
private ClientDetailsEntity clientDetails;
|
||||
|
||||
|
@ -81,21 +82,6 @@ public class WhitelistedSite {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userInfo
|
||||
*/
|
||||
@Basic
|
||||
public String getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userInfo the userInfo to set
|
||||
*/
|
||||
public void setUserInfo(String userInfo) {
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientDetails
|
||||
*/
|
||||
|
@ -126,4 +112,14 @@ public class WhitelistedSite {
|
|||
public void setAllowedScopes(Set<String> allowedScopes) {
|
||||
this.allowedScopes = allowedScopes;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="userinfo_id")
|
||||
public UserInfo getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(UserInfo creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ package org.mitre.openid.connect.repository;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
|
||||
/**
|
||||
* WhitelistedSite repository interface
|
||||
|
@ -42,6 +44,22 @@ public interface WhitelistedSiteRepository {
|
|||
* @return a valid WhitelistedSite if it exists, null otherwise
|
||||
*/
|
||||
public WhitelistedSite getById(Long id);
|
||||
|
||||
/**
|
||||
* Find a WhitelistedSite by its associated ClientDetails reference
|
||||
*
|
||||
* @param client the Relying Party
|
||||
* @return the corresponding WhitelistedSite if one exists for the RP, or null
|
||||
*/
|
||||
public WhitelistedSite getByClientDetails(ClientDetails client);
|
||||
|
||||
/**
|
||||
* Return a collection of the WhitelistedSites created by a given user
|
||||
*
|
||||
* @param creator the UserInfo representing an admin who may have made some WhitelistedSites
|
||||
* @return the collection of corresponding WhitelistedSites, if any, or null
|
||||
*/
|
||||
public Collection<WhitelistedSite> getByCreator(UserInfo creator);
|
||||
|
||||
/**
|
||||
* Removes the given IdToken from the repository
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.service;
|
||||
|
||||
import org.mitre.openid.connect.model.DefaultUserInfo;
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
|
||||
/**
|
||||
|
@ -32,7 +31,7 @@ public interface UserInfoService {
|
|||
* @param userInfo
|
||||
* the UserInfo to be saved
|
||||
*/
|
||||
public void save(DefaultUserInfo userInfo);
|
||||
public void save(UserInfo userInfo);
|
||||
|
||||
/**
|
||||
* Get UserInfo for user id
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
|
||||
/**
|
||||
* Interface for WhitelistedSite service
|
||||
|
@ -25,6 +29,13 @@ import org.mitre.openid.connect.model.WhitelistedSite;
|
|||
*/
|
||||
public interface WhitelistedSiteService {
|
||||
|
||||
/**
|
||||
* Return a collection of all WhitelistedSite managed by this service
|
||||
*
|
||||
* @return the WhitelistedSite collection, or null
|
||||
*/
|
||||
public Collection<WhitelistedSite> getAll();
|
||||
|
||||
/**
|
||||
* Returns the WhitelistedSite for the given id
|
||||
*
|
||||
|
@ -34,6 +45,22 @@ public interface WhitelistedSiteService {
|
|||
*/
|
||||
public WhitelistedSite getById(Long id);
|
||||
|
||||
/**
|
||||
* Find a WhitelistedSite by its associated ClientDetails reference
|
||||
*
|
||||
* @param client the Relying Party
|
||||
* @return the corresponding WhitelistedSite if one exists for the RP, or null
|
||||
*/
|
||||
public WhitelistedSite getByClientDetails(ClientDetails client);
|
||||
|
||||
/**
|
||||
* Return a collection of the WhitelistedSites created by a given user
|
||||
*
|
||||
* @param creator the UserInfo representing an admin who may have made some WhitelistedSites
|
||||
* @return the collection of corresponding WhitelistedSites, if any, or null
|
||||
*/
|
||||
public Collection<WhitelistedSite> getByCreator(UserInfo creator);
|
||||
|
||||
/**
|
||||
* Removes the given WhitelistedSite from the repository
|
||||
*
|
||||
|
|
|
@ -4,5 +4,6 @@ CREATE TABLE approvedsite (
|
|||
clientdetails_id VARCHAR(256),
|
||||
creationDate DATE,
|
||||
accessDate DATE,
|
||||
timeoutDate DATE
|
||||
timeoutDate DATE,
|
||||
whitelistedsite_id VARCHAR(256)
|
||||
);
|
|
@ -23,8 +23,10 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.PersistenceContext;
|
||||
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.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -80,4 +82,22 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
public WhitelistedSite save(WhitelistedSite whiteListedSite) {
|
||||
return saveOrUpdate(whiteListedSite.getId(), manager, whiteListedSite);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public WhitelistedSite getByClientDetails(ClientDetails client) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByClientDetails", WhitelistedSite.class);
|
||||
query.setParameter("clientDetails", client);
|
||||
|
||||
return query.getSingleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<WhitelistedSite> getByCreator(UserInfo creator) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByUserInfo", WhitelistedSite.class);
|
||||
query.setParameter("userInfo", creator);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.service.impl;
|
||||
|
||||
import org.mitre.openid.connect.model.DefaultUserInfo;
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.repository.UserInfoRepository;
|
||||
import org.mitre.openid.connect.service.UserInfoService;
|
||||
|
@ -53,7 +52,7 @@ public class UserInfoServiceImpl implements UserInfoService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void save(DefaultUserInfo userInfo) {
|
||||
public void save(UserInfo userInfo) {
|
||||
userInfoRepository.save(userInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
|
||||
import org.mitre.openid.connect.service.WhitelistedSiteService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -71,4 +75,19 @@ public class WhitelistedSiteServiceImpl implements WhitelistedSiteService {
|
|||
return whitelistedSiteRepository.save(whitelistedSite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<WhitelistedSite> getAll() {
|
||||
return whitelistedSiteRepository.getAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhitelistedSite getByClientDetails(ClientDetails client) {
|
||||
return whitelistedSiteRepository.getByClientDetails(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<WhitelistedSite> getByCreator(UserInfo creator) {
|
||||
return whitelistedSiteRepository.getByCreator(creator);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,20 +15,98 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.token;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.ApprovedSite;
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.model.WhitelistedSite;
|
||||
import org.mitre.openid.connect.service.ApprovedSiteService;
|
||||
import org.mitre.openid.connect.service.UserInfoService;
|
||||
import org.mitre.openid.connect.service.WhitelistedSiteService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.provider.AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
|
||||
|
||||
/**
|
||||
* Custom User Approval Handler implementation which uses a concept of a whitelist,
|
||||
* blacklist, and greylist.
|
||||
*
|
||||
* Blacklisted sites will be caught and handled before this
|
||||
* point.
|
||||
*
|
||||
* Whitelisted sites will be automatically approved, and an ApprovedSite entry will
|
||||
* be created for the site the first time a given user access it.
|
||||
*
|
||||
* All other sites fall into the greylist - the user will be presented with the user
|
||||
* approval page upon their first visit
|
||||
* @author aanganes
|
||||
*
|
||||
*/
|
||||
public class JdbcUserApprovalHandler implements UserApprovalHandler {
|
||||
|
||||
@Autowired
|
||||
UserInfoService userInfoService;
|
||||
|
||||
@Autowired
|
||||
ApprovedSiteService approvedSiteService;
|
||||
|
||||
@Autowired
|
||||
WhitelistedSiteService whitelistedSiteService;
|
||||
|
||||
@Autowired
|
||||
ClientDetailsService clientDetailsService;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the user has already stored a positive approval decision for this site; or if the
|
||||
* site is whitelisted, approve it automatically.
|
||||
*
|
||||
* Otherwise, return false so that the user will see the approval page and can make their own decision.
|
||||
*
|
||||
* @param authorizationRequest the incoming authorization request
|
||||
* @param userAuthentication the Principal representing the currently-logged-in user
|
||||
*
|
||||
* @return true if the site is pre-approved, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean isApproved(AuthorizationRequest authorizationRequest,
|
||||
Authentication userAuthentication) {
|
||||
public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
|
||||
|
||||
//Check database to see if the user identified by the userAuthentication has stored an approval decision
|
||||
userAuthentication.getPrincipal();
|
||||
String userId = userAuthentication.getName();
|
||||
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
|
||||
|
||||
//lookup ApprovedSites by userId
|
||||
UserInfo user = userInfoService.getByUserId(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
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
WhitelistedSite ws = whitelistedSiteService.getByClientDetails(client);
|
||||
if (ws != null) {
|
||||
//Create an approved site
|
||||
ApprovedSite newAP = new ApprovedSite();
|
||||
newAP.setAccessDate(new Date());
|
||||
newAP.setWhitelistedSite(ws);
|
||||
newAP.setAllowedScopes(ws.getAllowedScopes());
|
||||
newAP.setCreationDate(new Date());
|
||||
newAP.setUserInfo(user);
|
||||
//TODO set timeout date?
|
||||
approvedSiteService.save(newAP);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ package org.mitre.openid.connect.web;
|
|||
import java.security.Principal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
||||
import org.mitre.openid.connect.exception.UnknownUserInfoSchemaException;
|
||||
import org.mitre.openid.connect.model.DefaultUserInfo;
|
||||
|
|
Loading…
Reference in New Issue