fix
This commit is contained in:
parent
41cdd9db70
commit
16954fc370
4 changed files with 82 additions and 9 deletions
|
@ -97,6 +97,8 @@ public interface OAuth2Constants {
|
|||
String AUDIENCE="audience";
|
||||
String SUBJECT_TOKEN="subject_token";
|
||||
String SUBJECT_TOKEN_TYPE="subject_token_type";
|
||||
String REQUESTED_TOKEN_TYPE="requested_token_type";
|
||||
String REQUESTED_ISSUER="requested_issuer";
|
||||
String ACCESS_TOKEN_TYPE="urn:ietf:params:oauth:token-type:access_token";
|
||||
String REFRESH_TOKEN_TYPE="urn:ietf:params:oauth:token-type:refresh_token";
|
||||
String JWT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:jwt";
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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.keycloak.broker.provider;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface TokenExchangeTo {
|
||||
/**
|
||||
*
|
||||
* @param authorizedClient client requesting exchange
|
||||
* @param tokenUserSession UserSessionModel of token exchanging from
|
||||
* @param tokenSubject UserModel of token exchanging from
|
||||
* @param token access token representation of token exchanging from
|
||||
* @param params form parameters received for requested exchange
|
||||
* @return
|
||||
*/
|
||||
Response exchangeTo(ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject, AccessToken token, MultivaluedMap<String, String> params);
|
||||
}
|
|
@ -564,19 +564,43 @@ public class TokenEndpoint {
|
|||
public Response buildTokenExchange() {
|
||||
event.detail(Details.AUTH_METHOD, "oauth_credentials");
|
||||
|
||||
String scope = formParams.getFirst(OAuth2Constants.SCOPE);
|
||||
String subjectToken = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN);
|
||||
String subjectTokenType = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
|
||||
if (subjectTokenType != null && !subjectTokenType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE)) {
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Invalid token type, must be access token", Response.Status.BAD_REQUEST);
|
||||
|
||||
}
|
||||
|
||||
|
||||
AuthenticationManager.AuthResult authResult = AuthenticationManager.verifyIdentityToken(session, realm, uriInfo, clientConnection, true, true, false, subjectToken, headers);
|
||||
if (authResult == null) {
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
String requestedIssuer = formParams.getFirst(OAuth2Constants.REQUESTED_ISSUER);
|
||||
|
||||
if (requestedIssuer == null) {
|
||||
|
||||
}
|
||||
|
||||
return exchangeClientToClient(authResult);
|
||||
}
|
||||
|
||||
public Response exchangeClientToClient(AuthenticationManager.AuthResult subject) {
|
||||
String requestedTokenType = formParams.getFirst(OAuth2Constants.REQUESTED_TOKEN_TYPE);
|
||||
if (requestedTokenType == null) {
|
||||
requestedTokenType = OAuth2Constants.REFRESH_TOKEN_TYPE;
|
||||
} else if (!requestedTokenType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE) && !requestedTokenType.equals(OAuth2Constants.REFRESH_TOKEN_TYPE)) {
|
||||
event.error(Errors.INVALID_REQUEST);
|
||||
throw new ErrorResponseException("unsupported_requested_token_type", "Unsupported requested token type", Response.Status.BAD_REQUEST);
|
||||
|
||||
}
|
||||
String audience = formParams.getFirst(OAuth2Constants.AUDIENCE);
|
||||
if (audience == null) {
|
||||
event.error(Errors.INVALID_REQUEST);
|
||||
throw new ErrorResponseException("invalid_audience", "No audience specified", Response.Status.BAD_REQUEST);
|
||||
throw new ErrorResponseException("invalid_audience", "Audience parameter required", Response.Status.BAD_REQUEST);
|
||||
|
||||
}
|
||||
ClientModel targetClient = null;
|
||||
|
@ -594,7 +618,7 @@ public class TokenEndpoint {
|
|||
}
|
||||
|
||||
boolean exchangeFromAllowed = false;
|
||||
for (String aud : authResult.getToken().getAudience()) {
|
||||
for (String aud : subject.getToken().getAudience()) {
|
||||
ClientModel audClient = realm.getClientByClientId(aud);
|
||||
if (audClient == null) continue;
|
||||
if (audClient.equals(client)) {
|
||||
|
@ -617,13 +641,15 @@ public class TokenEndpoint {
|
|||
throw new ErrorResponseException(OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
|
||||
}
|
||||
|
||||
String scope = formParams.getFirst(OAuth2Constants.SCOPE);
|
||||
|
||||
AuthenticationSessionModel authSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, targetClient, false);
|
||||
authSession.setAuthenticatedUser(authResult.getUser());
|
||||
authSession.setAuthenticatedUser(subject.getUser());
|
||||
authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
|
||||
authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
|
||||
|
||||
UserSessionModel userSession = authResult.getSession();
|
||||
UserSessionModel userSession = subject.getSession();
|
||||
event.session(userSession);
|
||||
|
||||
AuthenticationManager.setRolesAndMappersInSession(authSession);
|
||||
|
@ -637,10 +663,13 @@ public class TokenEndpoint {
|
|||
updateUserSessionFromClientAuth(userSession);
|
||||
|
||||
TokenManager.AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, targetClient, event, session, userSession, clientSession)
|
||||
.generateAccessToken()
|
||||
.generateRefreshToken();
|
||||
.generateAccessToken();
|
||||
responseBuilder.getAccessToken().issuedFor(client.getClientId());
|
||||
responseBuilder.getRefreshToken().issuedFor(client.getClientId());
|
||||
|
||||
if (requestedTokenType.equals(OAuth2Constants.REFRESH_TOKEN_TYPE)) {
|
||||
responseBuilder.generateRefreshToken();
|
||||
responseBuilder.getRefreshToken().issuedFor(client.getClientId());
|
||||
}
|
||||
|
||||
String scopeParam = clientSession.getNote(OAuth2Constants.SCOPE);
|
||||
if (TokenUtil.isOIDCRequest(scopeParam)) {
|
||||
|
|
|
@ -185,7 +185,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
authz.getStoreFactory().getPolicyStore().delete(manageMembersPermission.getId());
|
||||
}
|
||||
Policy viewMembersPermission = viewMembersPermission(group);
|
||||
if (viewMembersPermission == null) {
|
||||
if (viewMembersPermission != null) {
|
||||
authz.getStoreFactory().getPolicyStore().delete(viewMembersPermission.getId());
|
||||
}
|
||||
Policy manageMembershipPermission = manageMembershipPermission(group);
|
||||
|
|
Loading…
Reference in a new issue