A new service for AuthenticationHolder management

- The logic to create and query AuthenticationHolder entities have been
  moved to a service, and other services that depended on
  AuthenticationHolderRepository now depend on
  AuthenticationHolderEntityService

- An additionalInfo map collection has been added to
  SavedUserAuthentication. This map can be used to store other
  information related to user authentication (like authn type,
  attributes etc.)
pull/1611/head
Andrea Ceccanti 2016-09-01 18:35:06 +02:00
parent 8c5f34a979
commit ec28327605
11 changed files with 307 additions and 227 deletions

View File

@ -1,24 +1,23 @@
/******************************************************************************* /*******************************************************************************
* Copyright 2016 The MITRE Corporation * Copyright 2016 The MITRE Corporation and the MIT Internet Trust Consortium
* and the MIT Internet Trust Consortium
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* you may not use this file except in compliance with the License. * in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License
* distributed under the License is distributed on an "AS IS" BASIS, * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * or implied. See the License for the specific language governing permissions and limitations under
* See the License for the specific language governing permissions and * the License.
* limitations under the License.
*******************************************************************************/ *******************************************************************************/
package org.mitre.oauth2.model; package org.mitre.oauth2.model;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.CollectionTable; import javax.persistence.CollectionTable;
@ -31,6 +30,7 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient; import javax.persistence.Transient;
@ -45,143 +45,163 @@ import org.springframework.security.core.GrantedAuthority;
* *
*/ */
@Entity @Entity
@Table(name="saved_user_auth") @Table(name = "saved_user_auth")
public class SavedUserAuthentication implements Authentication { public class SavedUserAuthentication implements Authentication {
private static final long serialVersionUID = -1804249963940323488L; private static final long serialVersionUID = -1804249963940323488L;
private Long id; private Long id;
private String name; private String name;
private Collection<? extends GrantedAuthority> authorities; private Collection<? extends GrantedAuthority> authorities;
private boolean authenticated; private boolean authenticated;
private String sourceClass; private String sourceClass;
/** private Map<String, String> additionalInfo = new HashMap<>();
* Create a Saved Auth from an existing Auth token
*/
public SavedUserAuthentication(Authentication src) {
setName(src.getName());
setAuthorities(src.getAuthorities());
setAuthenticated(src.isAuthenticated());
if (src instanceof SavedUserAuthentication) { /**
// if we're copying in a saved auth, carry over the original class name * Create a Saved Auth from an existing Auth token
setSourceClass(((SavedUserAuthentication) src).getSourceClass()); */
} else { public SavedUserAuthentication(Authentication src) {
setSourceClass(src.getClass().getName()); setName(src.getName());
} setAuthorities(src.getAuthorities());
} setAuthenticated(src.isAuthenticated());
/** if (src instanceof SavedUserAuthentication) {
* Create an empty saved auth // if we're copying in a saved auth, carry over the original class name
*/ setSourceClass(((SavedUserAuthentication) src).getSourceClass());
public SavedUserAuthentication() { additionalInfo.putAll(((SavedUserAuthentication) src).getAdditionalInfo());
} else {
setSourceClass(src.getClass().getName());
}
}
} /**
* Create an empty saved auth
*/
public SavedUserAuthentication() {
/** }
* @return the id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public Long getId() {
return id;
}
/** /**
* @param id the id to set * @return the id
*/ */
public void setId(Long id) { @Id
this.id = id; @GeneratedValue(strategy = GenerationType.IDENTITY)
} @Column(name = "id")
public Long getId() {
return id;
}
@Override /**
@Basic * @param id the id to set
@Column(name="name") */
public String getName() { public void setId(Long id) {
return name; this.id = id;
} }
@Override @Override
@ElementCollection(fetch = FetchType.EAGER) @Basic
@CollectionTable( @Column(name = "name")
name="saved_user_auth_authority", public String getName() {
joinColumns=@JoinColumn(name="owner_id") return name;
) }
@Convert(converter = SimpleGrantedAuthorityStringConverter.class)
@Column(name="authority")
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override @Override
@Transient @ElementCollection(fetch = FetchType.EAGER)
public Object getCredentials() { @CollectionTable(name = "saved_user_auth_authority",
return ""; joinColumns = @JoinColumn(name = "owner_id") )
} @Convert(converter = SimpleGrantedAuthorityStringConverter.class)
@Column(name = "authority")
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override @Override
@Transient @Transient
public Object getDetails() { public Object getCredentials() {
return null; return "";
} }
@Override @Override
@Transient @Transient
public Object getPrincipal() { public Object getDetails() {
return getName(); return null;
} }
@Override @Override
@Basic @Transient
@Column(name="authenticated") public Object getPrincipal() {
public boolean isAuthenticated() { return getName();
return authenticated; }
}
@Override @Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { @Basic
this.authenticated = isAuthenticated; @Column(name = "authenticated")
} public boolean isAuthenticated() {
return authenticated;
}
/** @Override
* @return the sourceClass public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
*/ this.authenticated = isAuthenticated;
@Basic }
@Column(name="source_class")
public String getSourceClass() {
return sourceClass;
}
/** /**
* @param sourceClass the sourceClass to set * @return the sourceClass
*/ */
public void setSourceClass(String sourceClass) { @Basic
this.sourceClass = sourceClass; @Column(name = "source_class")
} public String getSourceClass() {
return sourceClass;
}
/** /**
* @param name the name to set * @param sourceClass the sourceClass to set
*/ */
public void setName(String name) { public void setSourceClass(String sourceClass) {
this.name = name; this.sourceClass = sourceClass;
} }
/** /**
* @param authorities the authorities to set * @param name the name to set
*/ */
public void setAuthorities(Collection<? extends GrantedAuthority> authorities) { public void setName(String name) {
if (authorities != null) { this.name = name;
this.authorities = new HashSet<>(authorities); }
} else {
this.authorities = null; /**
} * @param authorities the authorities to set
} */
public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
if (authorities != null) {
this.authorities = new HashSet<>(authorities);
} else {
this.authorities = null;
}
}
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name = "info_key")
@Column(name = "info_val", length = 256)
@CollectionTable(name = "saved_user_auth_info", joinColumns = @JoinColumn(name = "owner_id") )
/**
* @return the additionalInfo
*/
public Map<String, String> getAdditionalInfo() {
return additionalInfo;
}
/**
* @param additionalInfo the additionalInfo to set
*/
public void setAdditionalInfo(Map<String, String> additionalInfo) {
this.additionalInfo = additionalInfo;
}
} }

View File

@ -0,0 +1,15 @@
package org.mitre.oauth2.service;
import java.util.List;
import org.mitre.oauth2.model.AuthenticationHolderEntity;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
public interface AuthenticationHolderEntityService {
AuthenticationHolderEntity create(OAuth2Authentication authn);
void remove(AuthenticationHolderEntity holder);
List<AuthenticationHolderEntity> getOrphanedAuthenticationHolders();
}

View File

@ -0,0 +1,41 @@
package org.mitre.oauth2.service.impl;
import java.util.List;
import org.mitre.oauth2.model.AuthenticationHolderEntity;
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Service;
@Service("authenticationHolderEntityService")
public class DefaultAuthenticationHolderEntityService implements AuthenticationHolderEntityService {
private final AuthenticationHolderRepository repo;
@Autowired
public DefaultAuthenticationHolderEntityService(AuthenticationHolderRepository repo) {
this.repo = repo;
}
@Override
public AuthenticationHolderEntity create(OAuth2Authentication authn) {
AuthenticationHolderEntity holder = new AuthenticationHolderEntity();
holder.setAuthentication(authn);
return repo.save(holder);
}
@Override
public void remove(AuthenticationHolderEntity holder) {
repo.remove(holder);
}
@Override
public List<AuthenticationHolderEntity> getOrphanedAuthenticationHolders() {
return repo.getOrphanedAuthenticationHolders();
}
}

View File

@ -96,6 +96,13 @@ CREATE TABLE IF NOT EXISTS saved_user_auth_authority (
authority VARCHAR(256) authority VARCHAR(256)
); );
CREATE TABLE IF NOT EXISTS saved_user_auth_info (
owner_id BIGINT,
info_key VARCHAR(256),
info_val VARCHAR(256),
UNIQUE(owner_id,info_key)
);
CREATE TABLE IF NOT EXISTS client_authority ( CREATE TABLE IF NOT EXISTS client_authority (
owner_id BIGINT, owner_id BIGINT,
authority VARCHAR(256) authority VARCHAR(256)

View File

@ -96,6 +96,13 @@ CREATE TABLE IF NOT EXISTS saved_user_auth_authority (
authority VARCHAR(256) authority VARCHAR(256)
); );
CREATE TABLE IF NOT EXISTS saved_user_auth_info (
owner_id BIGINT,
info_key VARCHAR(256),
info_val VARCHAR(256),
UNIQUE(owner_id, info_key)
);
CREATE TABLE IF NOT EXISTS client_authority ( CREATE TABLE IF NOT EXISTS client_authority (
owner_id BIGINT, owner_id BIGINT,
authority VARCHAR(256) authority VARCHAR(256)

View File

@ -96,6 +96,13 @@ CREATE TABLE IF NOT EXISTS saved_user_auth_authority (
authority VARCHAR(256) authority VARCHAR(256)
); );
CREATE TABLE IF NOT EXISTS saved_user_auth_info (
owner_id BIGINT,
info_key VARCHAR(256),
info_val VARCHAR(256),
UNIQUE(owner_id, info_key)
);
CREATE TABLE IF NOT EXISTS client_authority ( CREATE TABLE IF NOT EXISTS client_authority (
owner_id BIGINT, owner_id BIGINT,
authority VARCHAR(256) authority VARCHAR(256)

View File

@ -24,8 +24,8 @@ import java.util.Date;
import org.mitre.oauth2.model.AuthenticationHolderEntity; import org.mitre.oauth2.model.AuthenticationHolderEntity;
import org.mitre.oauth2.model.AuthorizationCodeEntity; import org.mitre.oauth2.model.AuthorizationCodeEntity;
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
import org.mitre.oauth2.repository.AuthorizationCodeRepository; import org.mitre.oauth2.repository.AuthorizationCodeRepository;
import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -51,7 +51,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
private AuthorizationCodeRepository repository; private AuthorizationCodeRepository repository;
@Autowired @Autowired
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderEntityService authenticationHolderService;
private int authCodeExpirationSeconds = 60 * 5; // expire in 5 minutes by default private int authCodeExpirationSeconds = 60 * 5; // expire in 5 minutes by default
@ -70,9 +70,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
String code = generator.generate(); String code = generator.generate();
// attach the authorization so that we can look it up later // attach the authorization so that we can look it up later
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); AuthenticationHolderEntity authHolder = authenticationHolderService.create(authentication);
authHolder.setAuthentication(authentication);
authHolder = authenticationHolderRepository.save(authHolder);
// set the auth code to expire // set the auth code to expire
Date expiration = new Date(System.currentTimeMillis() + (getAuthCodeExpirationSeconds() * 1000L)); Date expiration = new Date(System.currentTimeMillis() + (getAuthCodeExpirationSeconds() * 1000L));

View File

@ -39,8 +39,8 @@ import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
import org.mitre.oauth2.model.PKCEAlgorithm; import org.mitre.oauth2.model.PKCEAlgorithm;
import org.mitre.oauth2.model.SystemScope; import org.mitre.oauth2.model.SystemScope;
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
import org.mitre.oauth2.repository.OAuth2TokenRepository; import org.mitre.oauth2.repository.OAuth2TokenRepository;
import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.oauth2.service.OAuth2TokenEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.mitre.oauth2.service.SystemScopeService; import org.mitre.oauth2.service.SystemScopeService;
@ -83,7 +83,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
private OAuth2TokenRepository tokenRepository; private OAuth2TokenRepository tokenRepository;
@Autowired @Autowired
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderEntityService authenticationHolderService;
@Autowired @Autowired
private ClientDetailsEntityService clientDetailsService; private ClientDetailsEntityService clientDetailsService;
@ -237,9 +237,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
} }
// attach the authorization so that we can look it up later // attach the authorization so that we can look it up later
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); AuthenticationHolderEntity authHolder = authenticationHolderService.create(authentication);
authHolder.setAuthentication(authentication);
authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder); token.setAuthenticationHolder(authHolder);
@ -524,7 +522,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
logger.info("Found " + authHolders.size() + " orphaned authentication holders"); logger.info("Found " + authHolders.size() + " orphaned authentication holders");
} }
for(AuthenticationHolderEntity authHolder : authHolders) { for(AuthenticationHolderEntity authHolder : authHolders) {
authenticationHolderRepository.remove(authHolder); authenticationHolderService.remove(authHolder);
} }
} }
@ -537,7 +535,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
} }
private Collection<AuthenticationHolderEntity> getOrphanedAuthenticationHolders() { private Collection<AuthenticationHolderEntity> getOrphanedAuthenticationHolders() {
return Sets.newHashSet(authenticationHolderRepository.getOrphanedAuthenticationHolders()); return Sets.newHashSet(authenticationHolderService.getOrphanedAuthenticationHolders());
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@ -31,7 +31,7 @@ import org.mitre.jwt.signer.service.impl.SymmetricKeyJWTValidatorCacheService;
import org.mitre.oauth2.model.AuthenticationHolderEntity; import org.mitre.oauth2.model.AuthenticationHolderEntity;
import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.repository.AuthenticationHolderRepository; import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.mitre.oauth2.service.OAuth2TokenEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.mitre.oauth2.service.SystemScopeService; import org.mitre.oauth2.service.SystemScopeService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
@ -41,7 +41,6 @@ import org.mitre.openid.connect.web.AuthenticationTimeStamper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.OAuth2Request;
@ -79,7 +78,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
private JWTSigningAndValidationService jwtService; private JWTSigningAndValidationService jwtService;
@Autowired @Autowired
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderEntityService authenticationHolderService;
@Autowired @Autowired
private ConfigurationPropertiesBean configBean; private ConfigurationPropertiesBean configBean;
@ -279,9 +278,8 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
token.setClient(client); token.setClient(client);
token.setScope(scope); token.setScope(scope);
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); AuthenticationHolderEntity authHolder = authenticationHolderService.create(authentication);
authHolder.setAuthentication(authentication);
authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder); token.setAuthenticationHolder(authHolder);
JWTClaimsSet claims = new JWTClaimsSet.Builder() JWTClaimsSet claims = new JWTClaimsSet.Builder()
@ -336,16 +334,10 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
/** /**
* @return the authenticationHolderRepository * @return the authenticationHolderRepository
*/ */
public AuthenticationHolderRepository getAuthenticationHolderRepository() { public AuthenticationHolderEntityService getAuthenticationHolderService() {
return authenticationHolderRepository; return authenticationHolderService;
} }
/**
* @param authenticationHolderRepository the authenticationHolderRepository to set
*/
public void setAuthenticationHolderRepository(
AuthenticationHolderRepository authenticationHolderRepository) {
this.authenticationHolderRepository = authenticationHolderRepository;
}
} }

View File

@ -16,6 +16,17 @@
*******************************************************************************/ *******************************************************************************/
package org.mitre.oauth2.service.impl; package org.mitre.oauth2.service.impl;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -28,8 +39,8 @@ import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
import org.mitre.oauth2.model.SystemScope; import org.mitre.oauth2.model.SystemScope;
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
import org.mitre.oauth2.repository.OAuth2TokenRepository; import org.mitre.oauth2.repository.OAuth2TokenRepository;
import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.oauth2.service.SystemScopeService; import org.mitre.oauth2.service.SystemScopeService;
import org.mockito.AdditionalAnswers; import org.mockito.AdditionalAnswers;
@ -51,19 +62,6 @@ import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* @author wkim * @author wkim
* *
@ -95,7 +93,7 @@ public class TestDefaultOAuth2ProviderTokenService {
private OAuth2TokenRepository tokenRepository; private OAuth2TokenRepository tokenRepository;
@Mock @Mock
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderEntityService authenticationHolderService;
@Mock @Mock
private ClientDetailsEntityService clientDetailsService; private ClientDetailsEntityService clientDetailsService;
@ -114,7 +112,7 @@ public class TestDefaultOAuth2ProviderTokenService {
*/ */
@Before @Before
public void prepare() { public void prepare() {
Mockito.reset(tokenRepository, authenticationHolderRepository, clientDetailsService, tokenEnhancer); Mockito.reset(tokenRepository, authenticationHolderService, clientDetailsService, tokenEnhancer);
@ -153,7 +151,7 @@ public class TestDefaultOAuth2ProviderTokenService {
Mockito.when(storedAuthHolder.getAuthentication()).thenReturn(storedAuthentication); Mockito.when(storedAuthHolder.getAuthentication()).thenReturn(storedAuthentication);
Mockito.when(storedAuthentication.getOAuth2Request()).thenReturn(storedAuthRequest); Mockito.when(storedAuthentication.getOAuth2Request()).thenReturn(storedAuthRequest);
Mockito.when(authenticationHolderRepository.save(Matchers.any(AuthenticationHolderEntity.class))).thenReturn(storedAuthHolder); Mockito.when(authenticationHolderService.create(Matchers.any(OAuth2Authentication.class))).thenReturn(storedAuthHolder);
Mockito.when(scopeService.fromStrings(Matchers.anySet())).thenAnswer(new Answer<Set<SystemScope>>() { Mockito.when(scopeService.fromStrings(Matchers.anySet())).thenAnswer(new Answer<Set<SystemScope>>() {
@Override @Override
@ -260,7 +258,7 @@ public class TestDefaultOAuth2ProviderTokenService {
OAuth2AccessTokenEntity token = service.createAccessToken(authentication); OAuth2AccessTokenEntity token = service.createAccessToken(authentication);
Mockito.verify(clientDetailsService).loadClientByClientId(Matchers.anyString()); Mockito.verify(clientDetailsService).loadClientByClientId(Matchers.anyString());
Mockito.verify(authenticationHolderRepository).save(Matchers.any(AuthenticationHolderEntity.class)); Mockito.verify(authenticationHolderService).create(Matchers.any(OAuth2Authentication.class));
Mockito.verify(tokenEnhancer).enhance(Matchers.any(OAuth2AccessTokenEntity.class), Matchers.eq(authentication)); Mockito.verify(tokenEnhancer).enhance(Matchers.any(OAuth2AccessTokenEntity.class), Matchers.eq(authentication));
Mockito.verify(tokenRepository).saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class)); Mockito.verify(tokenRepository).saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class));
Mockito.verify(scopeService, Mockito.atLeastOnce()).removeReservedScopes(Matchers.anySet()); Mockito.verify(scopeService, Mockito.atLeastOnce()).removeReservedScopes(Matchers.anySet());
@ -344,12 +342,12 @@ public class TestDefaultOAuth2ProviderTokenService {
AuthenticationHolderEntity authHolder = Mockito.mock(AuthenticationHolderEntity.class); AuthenticationHolderEntity authHolder = Mockito.mock(AuthenticationHolderEntity.class);
Mockito.when(authHolder.getAuthentication()).thenReturn(authentication); Mockito.when(authHolder.getAuthentication()).thenReturn(authentication);
Mockito.when(authenticationHolderRepository.save(Matchers.any(AuthenticationHolderEntity.class))).thenReturn(authHolder); Mockito.when(authenticationHolderService.create(Matchers.any(OAuth2Authentication.class))).thenReturn(authHolder);
OAuth2AccessTokenEntity token = service.createAccessToken(authentication); OAuth2AccessTokenEntity token = service.createAccessToken(authentication);
assertThat(token.getAuthenticationHolder().getAuthentication(), equalTo(authentication)); assertThat(token.getAuthenticationHolder().getAuthentication(), equalTo(authentication));
Mockito.verify(authenticationHolderRepository).save(Matchers.any(AuthenticationHolderEntity.class)); Mockito.verify(authenticationHolderService).create(Matchers.any(OAuth2Authentication.class));
Mockito.verify(scopeService, Mockito.atLeastOnce()).removeReservedScopes(Matchers.anySet()); Mockito.verify(scopeService, Mockito.atLeastOnce()).removeReservedScopes(Matchers.anySet());
} }

View File

@ -1,18 +1,15 @@
/******************************************************************************* /*******************************************************************************
* Copyright 2016 The MITRE Corporation * Copyright 2016 The MITRE Corporation and the MIT Internet Trust Consortium
* and the MIT Internet Trust Consortium
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* you may not use this file except in compliance with the License. * in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License
* distributed under the License is distributed on an "AS IS" BASIS, * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * or implied. See the License for the specific language governing permissions and limitations under
* See the License for the specific language governing permissions and * the License.
* limitations under the License.
*******************************************************************************/ *******************************************************************************/
package org.mitre.uma.service.impl; package org.mitre.uma.service.impl;
@ -26,7 +23,7 @@ import org.mitre.jwt.signer.service.JWTSigningAndValidationService;
import org.mitre.oauth2.model.AuthenticationHolderEntity; import org.mitre.oauth2.model.AuthenticationHolderEntity;
import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.repository.AuthenticationHolderRepository; import org.mitre.oauth2.service.AuthenticationHolderEntityService;
import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.oauth2.service.OAuth2TokenEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
@ -52,70 +49,70 @@ import com.nimbusds.jwt.SignedJWT;
@Service("defaultUmaTokenService") @Service("defaultUmaTokenService")
public class DefaultUmaTokenService implements UmaTokenService { public class DefaultUmaTokenService implements UmaTokenService {
@Autowired @Autowired
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderEntityService authenticationHolderService;
@Autowired @Autowired
private OAuth2TokenEntityService tokenService; private OAuth2TokenEntityService tokenService;
@Autowired @Autowired
private ClientDetailsEntityService clientService; private ClientDetailsEntityService clientService;
@Autowired @Autowired
private ConfigurationPropertiesBean config; private ConfigurationPropertiesBean config;
@Autowired @Autowired
private JWTSigningAndValidationService jwtService; private JWTSigningAndValidationService jwtService;
@Override @Override
public OAuth2AccessTokenEntity createRequestingPartyToken(OAuth2Authentication o2auth, PermissionTicket ticket, Policy policy) { public OAuth2AccessTokenEntity createRequestingPartyToken(OAuth2Authentication o2auth,
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); PermissionTicket ticket, Policy policy) {
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
authHolder.setAuthentication(o2auth);
authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder); AuthenticationHolderEntity authHolder = authenticationHolderService.create(o2auth);
ClientDetailsEntity client = clientService.loadClientByClientId(o2auth.getOAuth2Request().getClientId()); token.setAuthenticationHolder(authHolder);
token.setClient(client);
Set<String> ticketScopes = ticket.getPermission().getScopes(); ClientDetailsEntity client =
Set<String> policyScopes = policy.getScopes(); clientService.loadClientByClientId(o2auth.getOAuth2Request().getClientId());
token.setClient(client);
Permission perm = new Permission(); Set<String> ticketScopes = ticket.getPermission().getScopes();
perm.setResourceSet(ticket.getPermission().getResourceSet()); Set<String> policyScopes = policy.getScopes();
perm.setScopes(new HashSet<>(Sets.intersection(ticketScopes, policyScopes)));
token.setPermissions(Sets.newHashSet(perm)); Permission perm = new Permission();
perm.setResourceSet(ticket.getPermission().getResourceSet());
perm.setScopes(new HashSet<>(Sets.intersection(ticketScopes, policyScopes)));
JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder(); token.setPermissions(Sets.newHashSet(perm));
claims.audience(Lists.newArrayList(ticket.getPermission().getResourceSet().getId().toString())); JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder();
claims.issuer(config.getIssuer());
claims.jwtID(UUID.randomUUID().toString());
if (config.getRqpTokenLifeTime() != null) { claims.audience(Lists.newArrayList(ticket.getPermission().getResourceSet().getId().toString()));
Date exp = new Date(System.currentTimeMillis() + config.getRqpTokenLifeTime() * 1000L); claims.issuer(config.getIssuer());
claims.jwtID(UUID.randomUUID().toString());
claims.expirationTime(exp); if (config.getRqpTokenLifeTime() != null) {
token.setExpiration(exp); Date exp = new Date(System.currentTimeMillis() + config.getRqpTokenLifeTime() * 1000L);
}
claims.expirationTime(exp);
token.setExpiration(exp);
}
JWSAlgorithm signingAlgorithm = jwtService.getDefaultSigningAlgorithm(); JWSAlgorithm signingAlgorithm = jwtService.getDefaultSigningAlgorithm();
JWSHeader header = new JWSHeader(signingAlgorithm, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(signingAlgorithm, null, null, null, null, null, null, null,
jwtService.getDefaultSignerKeyId(), null, null, jwtService.getDefaultSignerKeyId(), null, null);
null, null); SignedJWT signed = new SignedJWT(header, claims.build());
SignedJWT signed = new SignedJWT(header, claims.build());
jwtService.signJwt(signed); jwtService.signJwt(signed);
token.setJwt(signed); token.setJwt(signed);
tokenService.saveAccessToken(token); tokenService.saveAccessToken(token);
return token; return token;
} }
} }