Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9f6e5d9
Bump Java version to 1.8
NicolasLiampotis Aug 2, 2016
bb91b05
Add support for eduPersonUniqueId attribute
NicolasLiampotis Aug 3, 2016
1dfee04
Generate global sub id when eduPersonUniqueId is present
NicolasLiampotis Aug 25, 2016
e6fc1ef
Clean up unused imports and missing serial version IDs
NicolasLiampotis Aug 25, 2016
f176466
Limit supported claims based on R&S attribute bundle
NicolasLiampotis Aug 25, 2016
8aae75f
Adjust column sizes to support UTF8 character encoding in MySQL
NicolasLiampotis Sep 1, 2016
2ba8563
Fix sub column length which should not exceed 255 chars
NicolasLiampotis Sep 2, 2016
f10421b
Remove unused tables/columns from db migration scripts
NicolasLiampotis Sep 2, 2016
a15bc60
Fix access_token index length which should not exceed 255 chars
NicolasLiampotis Sep 5, 2016
b8a127b
Update build to use latest MITREid Connect version
NicolasLiampotis Sep 5, 2016
ab47126
Update Clients template based on upstream v1.2.6
NicolasLiampotis Sep 5, 2016
c75e8ea
Update header tag based on upstream version 1.2.6
NicolasLiampotis Sep 5, 2016
1a8bee7
Update build to use latest MySQL JDBC driver
NicolasLiampotis Sep 5, 2016
32f2d9e
Add support for acr claim based on eduPersonAssurance attribute value
NicolasLiampotis Sep 12, 2016
4fa522c
Logout feature
nikosev Aug 30, 2017
40b81ef
Redirect logout feature
nikosev Aug 30, 2017
92483fa
Upstream Web UI
nikosev Aug 31, 2017
4431ac7
ROLE_USER has access to API
nikosev Aug 31, 2017
8cf2017
Manage Services for OpenConext 1.2.6
nikosev Aug 31, 2017
4357cb5
Fix scopes, messages and empty table
nikosev Feb 4, 2018
17ebc62
OpenConext-OIDC connect to PostgreSQL database
nikosev Feb 4, 2018
80565ce
Add token lifetime and default values
nikosev Sep 28, 2018
caafb2d
Remove mySQL scripts and update PostgreSQL script
nikosev Sep 28, 2018
2baee6b
Add token-exchange grant type
nikosev Oct 3, 2018
8327451
UI modification - remove pages and css changes
nikosev Oct 4, 2018
cfd99b4
Add new file with messages to override the defaults
nikosev Oct 4, 2018
0f5fb71
Add new claims for refeds_edu scope
nikosev Oct 11, 2018
887e331
Fix claim mapping
nikosev Oct 11, 2018
773bc15
Remove default clients and resource servers
nikosev Oct 11, 2018
09502ab
Forbid token-exchange grant type on heart mode
nikosev Oct 11, 2018
18d9022
Allow dynamic registration of clients with grant type token-exchange
nikosev Oct 19, 2018
5b744af
Don't allow token response if client has no scopes defined
nikosev Oct 19, 2018
51ef75c
Override and fix token lifetime
nikosev Oct 19, 2018
77c98ae
Customize migration scripts
nikosev Oct 23, 2018
90f571f
Add default system scopes
nikosev Oct 25, 2018
0a99aee
Add option to select which claims will be displayed
nikosev Oct 30, 2018
b98cb7f
Fix information contained in well_known_configuration.json
nikosev Oct 30, 2018
0beec7c
Add token timeout values to application.oidc.properties
nikosev Oct 30, 2018
3c08cff
Minor fix for default token timeout value
nikosev Oct 30, 2018
7d1e267
Fix syntax error in scope.sql
nikosev Nov 2, 2018
c136863
Fix update user_info on login
nikosev Nov 30, 2018
15540fc
Fix 'Unable to find authentication timestamp' error
nikosev Nov 30, 2018
40ed31a
Update text of 'client-id-help'
nikosev Nov 30, 2018
9ae253b
Update well_known_configuration values
nikosev Nov 30, 2018
cc4be45
Remove junk from FederatedUserApprovalHandler
nikosev Dec 11, 2018
2b477ef
Change requesterID format
nikosev Dec 17, 2018
9c51732
Json header for well-known configuration
nikosev Jan 7, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .java_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7
1.8
7 changes: 4 additions & 3 deletions oidc-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,10 @@
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.2.5</version>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql-jdbc-driver.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
Expand Down
162 changes: 162 additions & 0 deletions oidc-server/src/main/java/oauth2/token/TokenExchangeTokenGranter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**
* Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2016-2018
*
* Modifications copyright (C) 2018 GRNET - Greek Research and Technology Network S.A.
*
* 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 oauth2.token;

import static java.lang.String.format;

import java.util.Optional;
import java.util.Set;

import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.mitre.oauth2.service.SystemScopeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Primary;

import com.google.common.base.Strings;
import com.google.common.collect.Sets;

@Primary
@Component("tokenExchangeTokenGranter")
public class TokenExchangeTokenGranter extends AbstractTokenGranter {

public static final Logger LOG = LoggerFactory.getLogger(TokenExchangeTokenGranter.class);

public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange";
private static final String TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
private static final String AUDIENCE_FIELD = "audience";

private final OAuth2TokenEntityService tokenServices;
private final SystemScopeService systemScopeService;

@Autowired
public TokenExchangeTokenGranter(final OAuth2TokenEntityService tokenServices, final ClientDetailsEntityService clientDetailsService, final OAuth2RequestFactory requestFactory, final SystemScopeService systemScopeService) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.tokenServices = tokenServices;
this.systemScopeService = systemScopeService;
}

protected Set<String> loadSystemScopes() {
final Set<String> systemScopes = Sets.newHashSet();

systemScopes.addAll(systemScopeService.toStrings(systemScopeService.getUnrestricted()));
systemScopes.addAll(systemScopeService.toStrings(systemScopeService.getRestricted()));

return systemScopes;
}

protected void validateScopeExchange(final ClientDetails actorClient, final TokenRequest tokenRequest, OAuth2AccessTokenEntity subjectToken) {
/**
* These scopes, in order to be "exchanged" across services, need to be present
* in the set of scopes linked to the subject token that is presented for the
* exchange.
*/
final Set<String> systemScopes = loadSystemScopes();

String audience = tokenRequest.getRequestParameters().get(AUDIENCE_FIELD);

ClientDetailsEntity subjectClient = subjectToken.getClient();

Set<String> requestedScopes = tokenRequest.getScope();
Set<String> actorScopes = actorClient.getScope();
Set<String> subjectTokenScopes = subjectToken.getScope();

LOG.info("Client '{}' requests token exchange from client '{}' to impersonate user '{}' on audience '{}' with scopes '{}'", actorClient.getClientId(), subjectClient.getClientId(), subjectToken.getAuthenticationHolder().getUserAuth().getName(), audience, requestedScopes);

LOG.debug("System scopes: {}", systemScopes);
LOG.debug("Requested scopes: {}", requestedScopes);
LOG.debug("Actor scopes: {}", actorScopes);
LOG.debug("Subject token scopes: {}", subjectTokenScopes);

// Ensure that actor can only request scopes allowed by its configuration
if (!actorScopes.containsAll(requestedScopes)) {
String errorMsg = String.format("Client \'%s\' requested a scope that is not allowed to request", actorClient.getClientId());

throw new InvalidScopeException(errorMsg, requestedScopes);
}

for (String rs : requestedScopes) {
if (systemScopes.contains(rs) && !subjectTokenScopes.contains(rs)) {
LOG.error("Requested scope '{}' is a system scope but not linked to subject token scopes", rs);
throw new InvalidScopeException(String.format("Requested scope \'%s\' is a system scope but not linked to subject token", rs));
}
}
}

@Override
protected OAuth2Authentication getOAuth2Authentication(final ClientDetails actorClient, final TokenRequest tokenRequest) {

if (tokenRequest.getRequestParameters().get("actor_token") != null || tokenRequest.getRequestParameters().get("want_composite") != null) {
throw new InvalidRequestException("Delegation not supported");
}

String subjectTokenType = tokenRequest.getRequestParameters().get("subject_token_type");
if (subjectTokenType == null) {
throw new InvalidRequestException("subject_token_type parameter is missing");
} else if (!subjectTokenType.equals(TOKEN_TYPE)) {
throw new InvalidRequestException(String.format("subject_type should be: \'%s\'", TOKEN_TYPE));
}

String subjectTokenValue = tokenRequest.getRequestParameters().get("subject_token");
LOG.debug("Subject token: {}", subjectTokenValue);
if (subjectTokenValue == null) {
throw new InvalidRequestException("subject_token parameter is missing");
}
OAuth2AccessTokenEntity subjectToken = tokenServices.readAccessToken(subjectTokenValue);

// Does token exchange among clients acting on behalf of themselves make sense?
if (subjectToken.getAuthenticationHolder().getUserAuth() == null) {
throw new InvalidRequestException("No user identity linked to subject token.");
}

validateScopeExchange(actorClient, tokenRequest, subjectToken);

OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(actorClient, tokenRequest), subjectToken.getAuthenticationHolder().getAuthentication().getUserAuthentication());

String audience = tokenRequest.getRequestParameters().get(AUDIENCE_FIELD);
if (!Strings.isNullOrEmpty(audience)) {
authentication.getOAuth2Request().getExtensions().put("aud", audience);
}

return authentication;
}

@Override
protected OAuth2AccessToken getAccessToken(final ClientDetails client, final TokenRequest tokenRequest) {
OAuth2Authentication auth = getOAuth2Authentication(client, tokenRequest);
OAuth2AccessToken accessToken = tokenServices.createAccessToken(auth);
accessToken.getAdditionalInformation().put("issued_token_type", TOKEN_TYPE);

return accessToken;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

Expand Down
Loading