KEYCLOAK-3882 Split server-spi into server-spi and server-spi-private
This commit is contained in:
1 parent
52a4509ada
commit
7e33f4a7d1
399 files changed
+551
-272
No files matched your search
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Non-recoverable error thrown during server startup
|
||||
*
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ServerStartupError extends Error {
|
||||
|
||||
private final boolean fillStackTrace;
|
||||
|
||||
public ServerStartupError(String message) {
|
||||
super(message);
|
||||
fillStackTrace = true;
|
||||
}
|
||||
|
||||
public ServerStartupError(String message, boolean fillStackTrace) {
|
||||
super(message);
|
||||
this.fillStackTrace = fillStackTrace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
if (fillStackTrace) {
|
||||
return super.fillInStackTrace();
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-192
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
import org.keycloak.services.managers.BruteForceProtector;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface AbstractAuthenticationFlowContext {
|
||||
|
||||
/**
|
||||
* Current event builder being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EventBuilder getEvent();
|
||||
|
||||
/**
|
||||
* Create a refresh new EventBuilder to use within this context
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EventBuilder newEvent();
|
||||
|
||||
/**
|
||||
* The current execution in the flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AuthenticationExecutionModel getExecution();
|
||||
|
||||
/**
|
||||
* Current realm
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
RealmModel getRealm();
|
||||
|
||||
/**
|
||||
* Information about the IP address from the connecting HTTP client.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClientConnection getConnection();
|
||||
|
||||
/**
|
||||
* UriInfo of the current request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UriInfo getUriInfo();
|
||||
|
||||
/**
|
||||
* Current session
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
KeycloakSession getSession();
|
||||
|
||||
HttpRequest getHttpRequest();
|
||||
BruteForceProtector getProtector();
|
||||
|
||||
|
||||
/**
|
||||
* Get any configuration associated with the current execution
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AuthenticatorConfigModel getAuthenticatorConfig();
|
||||
|
||||
/**
|
||||
* This could be an error message forwarded from another authenticator that is restarting or continuing the flo. For example
|
||||
* the brokering API sends this when the broker failed authentication
|
||||
* and we want to continue authentication locally. forwardedErrorMessage can then be displayed by
|
||||
* whatever form is challenging.
|
||||
*/
|
||||
FormMessage getForwardedErrorMessage();
|
||||
|
||||
/**
|
||||
* This could be an success message forwarded from another authenticator that is restarting or continuing the flow. For example
|
||||
* a reset password sends an email, then resets the flow with a success message. forwardedSuccessMessage can then be displayed by
|
||||
* whatever form is challenging.
|
||||
*/
|
||||
FormMessage getForwardedSuccessMessage();
|
||||
|
||||
/**
|
||||
* Generates access code and updates clientsession timestamp
|
||||
* Access codes must be included in form action callbacks as a query parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String generateAccessCode();
|
||||
|
||||
|
||||
AuthenticationExecutionModel.Requirement getCategoryRequirementFromCurrentFlow(String authenticatorCategory);
|
||||
|
||||
/**
|
||||
* Mark the current execution as successful. The flow will then continue
|
||||
*
|
||||
*/
|
||||
void success();
|
||||
|
||||
/**
|
||||
* Aborts the current flow
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
void failure(AuthenticationFlowError error);
|
||||
|
||||
/**
|
||||
* Aborts the current flow.
|
||||
*
|
||||
* @param error
|
||||
* @param response Response that will be sent back to HTTP client
|
||||
*/
|
||||
void failure(AuthenticationFlowError error, Response response);
|
||||
|
||||
/**
|
||||
* Sends a challenge response back to the HTTP client. If the current execution requirement is optional, this response will not be
|
||||
* sent. If the current execution requirement is alternative, then this challenge will be sent if no other alternative
|
||||
* execution was successful.
|
||||
*
|
||||
* @param challenge
|
||||
*/
|
||||
void challenge(Response challenge);
|
||||
|
||||
/**
|
||||
* Sends the challenge back to the HTTP client irregardless of the current executionr equirement
|
||||
*
|
||||
* @param challenge
|
||||
*/
|
||||
void forceChallenge(Response challenge);
|
||||
|
||||
/**
|
||||
* Same behavior as challenge(), but the error count in brute force attack detection will be incremented.
|
||||
* For example, if a user enters in a bad password, the user is directed to try again, but Keycloak will keep track
|
||||
* of how many failures have happened.
|
||||
*
|
||||
* @param error
|
||||
* @param challenge
|
||||
*/
|
||||
void failureChallenge(AuthenticationFlowError error, Response challenge);
|
||||
|
||||
/**
|
||||
* There was no failure or challenge. The authenticator was attempted, but not fulfilled. If the current execution
|
||||
* requirement is alternative or optional, then this status is ignored by the flow.
|
||||
*
|
||||
*/
|
||||
void attempted();
|
||||
|
||||
/**
|
||||
* Get the current status of the current execution.
|
||||
*
|
||||
* @return may return null if not set yet.
|
||||
*/
|
||||
FlowStatus getStatus();
|
||||
|
||||
/**
|
||||
* Get the error condition of a failed execution.
|
||||
*
|
||||
* @return may return null if there was no error
|
||||
*/
|
||||
AuthenticationFlowError getError();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface AuthenticationFlow {
|
||||
String BASIC_FLOW = "basic-flow";
|
||||
String FORM_FLOW = "form-flow";
|
||||
String CLIENT_FLOW = "client-flow";
|
||||
|
||||
Response processAction(String actionExecution);
|
||||
Response processFlow();
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* This interface encapsulates information about an execution in an AuthenticationFlow. It is also used to set
|
||||
* the status of the execution being performed.
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface AuthenticationFlowContext extends AbstractAuthenticationFlowContext {
|
||||
|
||||
/**
|
||||
* Current user attached to this flow. It can return null if no user has been identified yet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UserModel getUser();
|
||||
|
||||
/**
|
||||
* Attach a specific user to this flow.
|
||||
*
|
||||
* @param user
|
||||
*/
|
||||
void setUser(UserModel user);
|
||||
|
||||
/**
|
||||
* Clear the user from the flow.
|
||||
*/
|
||||
void clearUser();
|
||||
|
||||
void attachUserSession(UserSessionModel userSession);
|
||||
|
||||
|
||||
/**
|
||||
* ClientSessionModel attached to this flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClientSessionModel getClientSession();
|
||||
|
||||
/**
|
||||
* Create a Freemarker form builder that presets the user, action URI, and a generated access code
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LoginFormsProvider form();
|
||||
|
||||
/**
|
||||
* Get the action URL for the required action.
|
||||
*
|
||||
* @param code client session access code
|
||||
* @return
|
||||
*/
|
||||
URI getActionUrl(String code);
|
||||
|
||||
/**
|
||||
* Get the action URL for the required action. This auto-generates the access code.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
URI getActionUrl();
|
||||
|
||||
/**
|
||||
* End the flow and redirect browser based on protocol specific respones. This should only be executed
|
||||
* in browser-based flows.
|
||||
*
|
||||
*/
|
||||
void cancelLogin();
|
||||
|
||||
/**
|
||||
* Reset the current flow to the beginning and restarts it.
|
||||
*
|
||||
*/
|
||||
void resetFlow();
|
||||
|
||||
/**
|
||||
* Fork the current flow. The client session will be cloned and set to point at the realm's browser login flow. The Response will be the result
|
||||
* of this fork. The previous flow will still be set at the current execution. This is used by reset password when it sends an email.
|
||||
* It sends an email linking to the current flow and redirects the browser to a new browser login flow.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
void fork();
|
||||
|
||||
/**
|
||||
* Fork the current flow. The client session will be cloned and set to point at the realm's browser login flow. The Response will be the result
|
||||
* of this fork. The previous flow will still be set at the current execution. This is used by reset password when it sends an email.
|
||||
* It sends an email linking to the current flow and redirects the browser to a new browser login flow.
|
||||
*
|
||||
* This method will set up a success message that will be displayed in the first page of the new flow
|
||||
*
|
||||
* @param message Corresponds to raw text or a message property defined in a message bundle
|
||||
*/
|
||||
void forkWithSuccessMessage(FormMessage message);
|
||||
/**
|
||||
* Fork the current flow. The client session will be cloned and set to point at the realm's browser login flow. The Response will be the result
|
||||
* of this fork. The previous flow will still be set at the current execution. This is used by reset password when it sends an email.
|
||||
* It sends an email linking to the current flow and redirects the browser to a new browser login flow.
|
||||
*
|
||||
* This method will set up an error message that will be displayed in the first page of the new flow
|
||||
*
|
||||
* @param message Corresponds to raw text or a message property defined in a message bundle
|
||||
*/
|
||||
void forkWithErrorMessage(FormMessage message);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
/**
|
||||
* Set of error codes that can be thrown by an Authenticator, FormAuthenticator, or FormAction
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public enum AuthenticationFlowError {
|
||||
EXPIRED_CODE,
|
||||
INVALID_CLIENT_SESSION,
|
||||
INVALID_USER,
|
||||
INVALID_CREDENTIALS,
|
||||
CREDENTIAL_SETUP_REQUIRED,
|
||||
USER_DISABLED,
|
||||
USER_CONFLICT,
|
||||
USER_TEMPORARILY_DISABLED,
|
||||
INTERNAL_ERROR,
|
||||
UNKNOWN_USER,
|
||||
FORK_FLOW,
|
||||
UNKNOWN_CLIENT,
|
||||
CLIENT_NOT_FOUND,
|
||||
CLIENT_DISABLED,
|
||||
CLIENT_CREDENTIALS_SETUP_REQUIRED,
|
||||
INVALID_CLIENT_CREDENTIALS,
|
||||
|
||||
IDENTITY_PROVIDER_NOT_FOUND,
|
||||
IDENTITY_PROVIDER_DISABLED,
|
||||
IDENTITY_PROVIDER_ERROR
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
/**
|
||||
* Throw this exception from an Authenticator, FormAuthenticator, or FormAction if you want to completely abort the flow.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AuthenticationFlowException extends RuntimeException {
|
||||
private AuthenticationFlowError error;
|
||||
|
||||
public AuthenticationFlowException(AuthenticationFlowError error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AuthenticationFlowException(String message, AuthenticationFlowError error) {
|
||||
super(message);
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AuthenticationFlowException(String message, Throwable cause, AuthenticationFlowError error) {
|
||||
super(message, cause);
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AuthenticationFlowException(Throwable cause, AuthenticationFlowError error) {
|
||||
super(cause);
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AuthenticationFlowException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, AuthenticationFlowError error) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AuthenticationFlowError getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* This interface is for users that want to add custom authenticators to an authentication flow.
|
||||
* You must implement this interface as well as an AuthenticatorFactory.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface Authenticator extends Provider {
|
||||
|
||||
/**
|
||||
* Initial call for the authenticator. This method should check the current HTTP request to determine if the request
|
||||
* satifies the Authenticator's requirements. If it doesn't, it should send back a challenge response by calling
|
||||
* the AuthenticationFlowContext.challenge(Response). If this challenge is a authentication, the action URL
|
||||
* of the form must point to
|
||||
*
|
||||
* /realms/{realm}/login-actions/authenticate?code={session-code}&execution={executionId}
|
||||
*
|
||||
* or
|
||||
*
|
||||
* /realms/{realm}/login-actions/registration?code={session-code}&execution={executionId}
|
||||
*
|
||||
* {session-code} pertains to the code generated from AuthenticationFlowContext.generateAccessCode(). The {executionId}
|
||||
* pertains to the AuthenticationExecutionModel.getId() value obtained from AuthenticationFlowContext.getExecution().
|
||||
*
|
||||
* The action URL will invoke the action() method described below.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void authenticate(AuthenticationFlowContext context);
|
||||
|
||||
/**
|
||||
* Called from a form action invocation.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void action(AuthenticationFlowContext context);
|
||||
|
||||
|
||||
/**
|
||||
* Does this authenticator require that the user has already been identified? That AuthenticatorContext.getUser() is not null?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean requiresUser();
|
||||
|
||||
/**
|
||||
* Is this authenticator configured for this user.
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
/**
|
||||
* Set actions to configure authenticator
|
||||
*
|
||||
*/
|
||||
void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* Factory for creating Authenticator instances. This is a singleton and created when Keycloak boots.
|
||||
*
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.AuthenticatorFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your AuthenticatorFactory classes
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface AuthenticatorFactory extends ProviderFactory<Authenticator>, ConfigurableAuthenticatorFactory {
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class AuthenticatorSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "authenticator";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return Authenticator.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return AuthenticatorFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Encapsulates information about the execution in ClientAuthenticationFlow
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientAuthenticationFlowContext extends AbstractAuthenticationFlowContext {
|
||||
|
||||
/**
|
||||
* Current client attached to this flow. It can return null if no client has been identified yet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClientModel getClient();
|
||||
|
||||
/**
|
||||
* Attach a specific client to this flow.
|
||||
*
|
||||
* @param client
|
||||
*/
|
||||
void setClient(ClientModel client);
|
||||
|
||||
/**
|
||||
* Return the map where the authenticators can put some additional state related to authenticated client and the context how was
|
||||
* client authenticated (ie. attributes from client certificate etc). Map is writable, so you can add/remove items from it as needed.
|
||||
*
|
||||
* After successful authentication will be those state data put into UserSession notes. This allows you to configure
|
||||
* UserSessionNote protocol mapper for your client, which will allow to map those state data into the access token available in the application
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> getClientAuthAttributes();
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* This interface is for users that want to add custom client authenticators to an authentication flow.
|
||||
* You must implement this interface as well as a ClientAuthenticatorFactory.
|
||||
*
|
||||
* This interface is for verifying client credentials from request. On the adapter side, you must also implement org.keycloak.adapters.authentication.ClientCredentialsProvider , which is supposed
|
||||
* to add the client credentials to the request, which will ClientAuthenticator verify on server side
|
||||
*
|
||||
* @see org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator
|
||||
* @see org.keycloak.authentication.authenticators.client.JWTClientAuthenticator
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientAuthenticator extends Provider {
|
||||
|
||||
/**
|
||||
* Initial call for the authenticator. This method should check the current HTTP request to determine if the request
|
||||
* satisfies the ClientAuthenticator's requirements. If it doesn't, it should send back a challenge response by calling
|
||||
* the ClientAuthenticationFlowContext.challenge(Response).
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void authenticateClient(ClientAuthenticationFlowContext context);
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Factory for creating ClientAuthenticator instances. This is a singleton and created when Keycloak boots.
|
||||
*
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.ClientAuthenticatorFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your ClientAuthenticatorFactory classes
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientAuthenticatorFactory extends ProviderFactory<ClientAuthenticator>, ConfigurableAuthenticatorFactory {
|
||||
ClientAuthenticator create();
|
||||
|
||||
/**
|
||||
* Is this authenticator configurable globally?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
boolean isConfigurable();
|
||||
|
||||
/**
|
||||
* List of config properties for this client implementation. Those will be shown in admin console in clients credentials tab and can be configured per client.
|
||||
* Applicable only if "isConfigurablePerClient" is true
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ProviderConfigProperty> getConfigPropertiesPerClient();
|
||||
|
||||
/**
|
||||
* Get configuration, which needs to be used for adapter ( keycloak.json ) of particular client. Some implementations
|
||||
* may return just template and user needs to edit the values according to his environment (For example fill the location of keystore file)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> getAdapterConfiguration(ClientModel client);
|
||||
|
||||
/**
|
||||
* Get authentication methods for the specified protocol
|
||||
*
|
||||
* @param loginProtocol corresponds to {@link org.keycloak.protocol.LoginProtocolFactory#getId}
|
||||
* @return name of supported client authenticator methods in the protocol specific "language"
|
||||
*/
|
||||
Set<String> getProtocolAuthenticatorMethods(String loginProtocol);
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientAuthenticatorSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "client-authenticator";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return ClientAuthenticator.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return ClientAuthenticatorFactory.class;
|
||||
}
|
||||
}
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.provider.ConfiguredProvider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ConfigurableAuthenticatorFactory extends ConfiguredProvider {
|
||||
/**
|
||||
* Friendly name for the authenticator
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDisplayType();
|
||||
|
||||
/**
|
||||
* General authenticator type, i.e. totp, password, cert.
|
||||
*
|
||||
* @return null if not a referencable category
|
||||
*/
|
||||
String getReferenceCategory();
|
||||
|
||||
/**
|
||||
* Is this authenticator configurable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isConfigurable();
|
||||
|
||||
/**
|
||||
* What requirement settings are allowed.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AuthenticationExecutionModel.Requirement[] getRequirementChoices();
|
||||
|
||||
/**
|
||||
*
|
||||
* Does this authenticator have required actions that can set if the user does not have
|
||||
* this authenticator set up?
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isUserSetupAllowed();
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
/**
|
||||
* Status of an execution/authenticator in a Authentication Flow
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public enum FlowStatus {
|
||||
/**
|
||||
* Successful execution
|
||||
*/
|
||||
SUCCESS,
|
||||
|
||||
/**
|
||||
* Execution offered a challenge. Optional executions will ignore this challenge. Alternative executions may
|
||||
* ignore the challenge depending on the status of other executions in the flow.
|
||||
*
|
||||
*/
|
||||
CHALLENGE,
|
||||
|
||||
/**
|
||||
* Irregardless of the execution's requirement, this challenge will be sent to the user.
|
||||
*
|
||||
*/
|
||||
FORCE_CHALLENGE,
|
||||
|
||||
/**
|
||||
* Flow will be aborted and a Response provided by the execution will be sent.
|
||||
*
|
||||
*/
|
||||
FAILURE_CHALLENGE,
|
||||
|
||||
/**
|
||||
* Flow will be aborted.
|
||||
*
|
||||
*/
|
||||
FAILED,
|
||||
|
||||
/**
|
||||
* This is not an error condition. Execution was attempted, but the authenticator is unable to process the request. An example of this is if
|
||||
* a Kerberos authenticator did not see a negotiate header. There was no error, but the execution was attempted.
|
||||
*
|
||||
*/
|
||||
ATTEMPTED,
|
||||
|
||||
/**
|
||||
* This flow is being forked. The current client session is being cloned, reset, and redirected to browser login.
|
||||
*
|
||||
*/
|
||||
FORK,
|
||||
|
||||
/**
|
||||
* This flow was reset to the beginning. An example is hitting cancel on the OTP page which will bring you back to the
|
||||
* username password page.
|
||||
*
|
||||
*/
|
||||
FLOW_RESET
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
|
||||
/**
|
||||
* Thrown internally when authenticator wants to fork the current flow.
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ForkFlowException extends AuthenticationFlowException {
|
||||
protected FormMessage successMessage;
|
||||
protected FormMessage errorMessage;
|
||||
|
||||
public FormMessage getSuccessMessage() {
|
||||
return successMessage;
|
||||
}
|
||||
|
||||
public FormMessage getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public ForkFlowException(FormMessage successMessage, FormMessage errorMessage) {
|
||||
super(AuthenticationFlowError.FORK_FLOW);
|
||||
this.successMessage = successMessage;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* Fine grain processing of a form. Allows you to split up the processing of a form into smaller parts so that you can
|
||||
* enable/disable them from the admin console. For example, Recaptcha is a FormAction. This allows you as the admin
|
||||
* to turn Recaptcha on/off even though it is on the same form/page as other registration validation.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface FormAction extends Provider {
|
||||
/**
|
||||
* When a FormAuthenticator is rendering the challenge page, even FormAction.buildPage() method will be called
|
||||
* This gives the FormAction the opportunity to add additional attributes to the form to be displayed.
|
||||
*
|
||||
* @param context
|
||||
* @param form
|
||||
*/
|
||||
void buildPage(FormContext context, LoginFormsProvider form);
|
||||
/**
|
||||
* This is the first phase of form processing. Each FormAction.validate() method is called. This gives the
|
||||
* FormAction a chance to validate and challenge if user input is invalid.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void validate(ValidationContext context);
|
||||
|
||||
/**
|
||||
* Called after all validate() calls of all FormAction providers are successful.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void success(FormContext context);
|
||||
|
||||
/**
|
||||
* Does this FormAction require that a user be set? For registration, this method will always return false.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean requiresUser();
|
||||
|
||||
/**
|
||||
* Is this FormAction configured for the current user?
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
/**
|
||||
* Set actions to configure authenticator
|
||||
*
|
||||
*/
|
||||
void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* Factory for instantiating FormAction objects. This is a singleton and created when Keycloak boots.
|
||||
*
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.FormActionFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your FormActionFactory classes
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface FormActionFactory extends ProviderFactory<FormAction>, ConfigurableAuthenticatorFactory {
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class FormActionSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "form-action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return FormAction.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return FormActionFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* This class is responsible for rendering a form. The way it works is that each FormAction that is a child of this
|
||||
* FormAuthenticator, will have its buildPage() method call first, then the FormAuthenticator.render() method will be invoked.
|
||||
*
|
||||
* This gives each FormAction a chance to add information to the form in an independent manner.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface FormAuthenticator extends Provider {
|
||||
/**
|
||||
* Called to render the FormAuthenticator's challenge page. If null is returned, then success is assumed and the
|
||||
* next authenticator in the flow will be invoked.
|
||||
*
|
||||
* @param context
|
||||
* @param form
|
||||
* @return
|
||||
*/
|
||||
Response render(FormContext context, LoginFormsProvider form);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* Factory for instantiating FormAuthenticators. This is a singleton and created when Keycloak boots.
|
||||
*
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.FormAuthenticatorFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your FormAuthenticatorFactory classes
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface FormAuthenticatorFactory extends ProviderFactory<FormAuthenticator>, ConfigurableAuthenticatorFactory {
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class FormAuthenticatorSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "form-authenticator";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return FormAuthenticator.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return FormAuthenticatorFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* Interface that encapsulates the current state of the current form being executed
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface FormContext {
|
||||
/**
|
||||
* Current event builder being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EventBuilder getEvent();
|
||||
|
||||
/**
|
||||
* Create a refresh new EventBuilder to use within this context
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EventBuilder newEvent();
|
||||
|
||||
/**
|
||||
* The current execution in the flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AuthenticationExecutionModel getExecution();
|
||||
|
||||
/**
|
||||
* Current user attached to this flow. It can return null if no uesr has been identified yet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UserModel getUser();
|
||||
|
||||
/**
|
||||
* Attach a specific user to this flow.
|
||||
*
|
||||
* @param user
|
||||
*/
|
||||
void setUser(UserModel user);
|
||||
|
||||
/**
|
||||
* Current realm
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
RealmModel getRealm();
|
||||
|
||||
/**
|
||||
* ClientSessionModel attached to this flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClientSessionModel getClientSession();
|
||||
|
||||
/**
|
||||
* Information about the IP address from the connecting HTTP client.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClientConnection getConnection();
|
||||
|
||||
/**
|
||||
* UriInfo of the current request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UriInfo getUriInfo();
|
||||
|
||||
/**
|
||||
* Current session
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
KeycloakSession getSession();
|
||||
|
||||
HttpRequest getHttpRequest();
|
||||
|
||||
/**
|
||||
* Get any configuration associated with the current execution
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AuthenticatorConfigModel getAuthenticatorConfig();
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Interface that encapsulates current information about the current requred action
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RequiredActionContext {
|
||||
public static enum Status {
|
||||
CHALLENGE,
|
||||
SUCCESS,
|
||||
IGNORE,
|
||||
FAILURE
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action URL for the required action.
|
||||
*
|
||||
* @param code client sessino access code
|
||||
* @return
|
||||
*/
|
||||
URI getActionUrl(String code);
|
||||
|
||||
/**
|
||||
* Get the action URL for the required action. This auto-generates the access code.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
URI getActionUrl();
|
||||
|
||||
/**
|
||||
* Create a Freemarker form builder that presets the user, action URI, and a generated access code
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LoginFormsProvider form();
|
||||
|
||||
|
||||
/**
|
||||
* If challenge has been sent this returns the JAX-RS Response
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Response getChallenge();
|
||||
|
||||
|
||||
/**
|
||||
* Current event builder being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EventBuilder getEvent();
|
||||
|
||||
/**
|
||||
* Current user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UserModel getUser();
|
||||
RealmModel getRealm();
|
||||
ClientSessionModel getClientSession();
|
||||
UserSessionModel getUserSession();
|
||||
ClientConnection getConnection();
|
||||
UriInfo getUriInfo();
|
||||
KeycloakSession getSession();
|
||||
HttpRequest getHttpRequest();
|
||||
|
||||
/**
|
||||
* Generates access code and updates clientsession timestamp
|
||||
* Access codes must be included in form action callbacks as a query parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String generateCode();
|
||||
|
||||
Status getStatus();
|
||||
|
||||
/**
|
||||
* Send a challenge Response back to user
|
||||
*
|
||||
* @param response
|
||||
*/
|
||||
void challenge(Response response);
|
||||
|
||||
/**
|
||||
* Abort the authentication with an error
|
||||
*
|
||||
*/
|
||||
void failure();
|
||||
|
||||
/**
|
||||
* Mark this required action as successful. The required action will be removed from the UserModel
|
||||
*
|
||||
*/
|
||||
void success();
|
||||
|
||||
/**
|
||||
* Ignore this required action and go onto the next, or complete the flow.
|
||||
*
|
||||
*/
|
||||
void ignore();
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.RequiredActionFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your RequiredActionFactory classes
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RequiredActionFactory extends ProviderFactory<RequiredActionProvider> {
|
||||
|
||||
/**
|
||||
* Display text used in admin console to reference this required action
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDisplayText();
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* RequiredAction provider. Required actions are one-time actions that a user must perform before they are logged in.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RequiredActionProvider extends Provider {
|
||||
/**
|
||||
* Called every time a uesr authenticates. This checks to see if this required action should be triggered.
|
||||
* The implementation of this method is responsible for setting the required action on the UserModel.
|
||||
*
|
||||
* For example, the UpdatePassword required actions checks the password policies to see if the password has expired.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void evaluateTriggers(RequiredActionContext context);
|
||||
|
||||
/**
|
||||
* If the user has a required action set, this method will be the initial call to obtain what to display to the
|
||||
* user's browser. Return null if no action should be done.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
void requiredActionChallenge(RequiredActionContext context);
|
||||
|
||||
/**
|
||||
* Called when a required action has form input you want to process.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void processAction(RequiredActionContext context);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class RequiredActionSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "required-action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return RequiredActionProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return RequiredActionFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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.authentication;
|
||||
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface that encapsulates the current validation that is being performed. Calling success() or validationError()
|
||||
* sets the status of this current validation.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ValidationContext extends FormContext {
|
||||
/**
|
||||
* Mark this validation as having a validation error
|
||||
*
|
||||
* @param formData form data you want to display when the form is refreshed
|
||||
* @param errors error messages to display on the form
|
||||
*/
|
||||
void validationError(MultivaluedMap<String, String> formData, List<FormMessage> errors);
|
||||
|
||||
void error(String error);
|
||||
|
||||
/**
|
||||
* Mark this validation as sucessful
|
||||
*
|
||||
*/
|
||||
void success();
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization;
|
||||
|
||||
import org.keycloak.authorization.permission.evaluator.Evaluators;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultPolicyEvaluator;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>The main contract here is the creation of {@link org.keycloak.authorization.permission.evaluator.PermissionEvaluator} instances. Usually
|
||||
* an application has a single {@link AuthorizationProvider} instance and threads servicing client requests obtain {@link org.keycloak.authorization.core.permission.evaluator.PermissionEvaluator}
|
||||
* from the {@link #evaluators()} method.
|
||||
*
|
||||
* <p>The internal state of a {@link AuthorizationProvider} is immutable. This internal state includes all of the metadata
|
||||
* used during the evaluation of policies.
|
||||
*
|
||||
* <p>Once created, {@link org.keycloak.authorization.permission.evaluator.PermissionEvaluator} instances can be obtained from the {@link #evaluators()} method:
|
||||
*
|
||||
* <pre>
|
||||
* List<ResourcePermission> permissionsToEvaluate = getPermissions(); // the permissions to evaluate
|
||||
* EvaluationContext evaluationContext = createEvaluationContext(); // the context with runtime environment information
|
||||
* PermissionEvaluator evaluator = authorization.evaluators().from(permissionsToEvaluate, context);
|
||||
*
|
||||
* evaluator.evaluate(new Decision() {
|
||||
*
|
||||
* public void onDecision(Evaluation evaluation) {
|
||||
* // do something on grant
|
||||
* }
|
||||
*
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public final class AuthorizationProvider implements Provider {
|
||||
|
||||
private final DefaultPolicyEvaluator policyEvaluator;
|
||||
private final Executor scheduller;
|
||||
private final StoreFactory storeFactory;
|
||||
private final List<PolicyProviderFactory> policyProviderFactories;
|
||||
private final KeycloakSession keycloakSession;
|
||||
private final RealmModel realm;
|
||||
|
||||
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory, Executor scheduller) {
|
||||
this.keycloakSession = session;
|
||||
this.realm = realm;
|
||||
this.storeFactory = storeFactory;
|
||||
this.scheduller = scheduller;
|
||||
this.policyProviderFactories = configurePolicyProviderFactories(session);
|
||||
this.policyEvaluator = new DefaultPolicyEvaluator(this, this.policyProviderFactories);
|
||||
}
|
||||
|
||||
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory) {
|
||||
this(session, realm, storeFactory, Runnable::run);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Evaluators} instance from where {@link org.keycloak.authorization.policy.evaluation.PolicyEvaluator} instances
|
||||
* can be obtained.
|
||||
*
|
||||
* @return a {@link Evaluators} instance
|
||||
*/
|
||||
public Evaluators evaluators() {
|
||||
return new Evaluators(this.policyProviderFactories, this.policyEvaluator, this.scheduller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link StoreFactory}.
|
||||
*
|
||||
* @return the {@link StoreFactory}
|
||||
*/
|
||||
public StoreFactory getStoreFactory() {
|
||||
return this.storeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered {@link PolicyProviderFactory}.
|
||||
*
|
||||
* @return a {@link List} containing all registered {@link PolicyProviderFactory}
|
||||
*/
|
||||
public List<PolicyProviderFactory> getProviderFactories() {
|
||||
return this.policyProviderFactories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link PolicyProviderFactory} given a <code>type</code>.
|
||||
*
|
||||
* @param type the type of the policy provider
|
||||
* @param <F> the expected type of the provider
|
||||
* @return a {@link PolicyProviderFactory} with the given <code>type</code>
|
||||
*/
|
||||
public <F extends PolicyProviderFactory> F getProviderFactory(String type) {
|
||||
return (F) getProviderFactories().stream().filter(policyProviderFactory -> policyProviderFactory.getId().equals(type)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public KeycloakSession getKeycloakSession() {
|
||||
return this.keycloakSession;
|
||||
}
|
||||
|
||||
public RealmModel getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
private List<PolicyProviderFactory> configurePolicyProviderFactories(KeycloakSession session) {
|
||||
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(PolicyProvider.class);
|
||||
|
||||
if (providerFactories.isEmpty()) {
|
||||
throw new RuntimeException("Could not find any policy provider.");
|
||||
}
|
||||
|
||||
return providerFactories.stream().map(providerFactory -> (PolicyProviderFactory) providerFactory).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface AuthorizationProviderFactory extends ProviderFactory<AuthorizationProvider> {
|
||||
|
||||
AuthorizationProvider create(KeycloakSession session, RealmModel realm);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class AuthorizationSpi implements Spi {
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "authorization";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return AuthorizationProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return AuthorizationProviderFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization;
|
||||
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Decision<D extends Evaluation> {
|
||||
|
||||
enum Effect {
|
||||
PERMIT,
|
||||
DENY
|
||||
}
|
||||
|
||||
void onDecision(D evaluation);
|
||||
|
||||
default void onError(Throwable cause) {
|
||||
throw new RuntimeException("Not implemented.", cause);
|
||||
}
|
||||
|
||||
default void onComplete() {
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.attribute;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>Holds attributes, their values and provides utlity methods to manage them.
|
||||
*
|
||||
* <p>In the future, it may be useful to provide different implementations for this interface in order to plug or integrate with different
|
||||
* Policy Information Point (PIP).</p>
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Attributes {
|
||||
|
||||
static Attributes from(Map<String, Collection<String>> attributes) {
|
||||
return () -> attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a {@link Map}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, Collection<String>> toMap();
|
||||
|
||||
/**
|
||||
* Checks if there is an attribute with the given <code>name</code>.
|
||||
*
|
||||
* @param name the attribute name
|
||||
* @return true if any attribute with <code>name</code> exist. Otherwise, returns false.
|
||||
*/
|
||||
default boolean exists(String name) {
|
||||
return toMap().containsKey(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an attribute with the given <code>name</code> and <code>value</code>.
|
||||
*
|
||||
* @param name the attribute name
|
||||
* @param value the attribute value
|
||||
* @return true if any attribute with <code>name</code> and <code>value</code> exist. Otherwise, returns false.
|
||||
*/
|
||||
default boolean containsValue(String name, String value) {
|
||||
Collection<String> values = toMap().get(name);
|
||||
return values != null && values.stream().anyMatch(value::equals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Entry} from where values can be obtained and parsed accordingly.
|
||||
*
|
||||
* @param name the attribute name
|
||||
* @return an {@link Entry} holding the values for an attribute
|
||||
*/
|
||||
default Entry getValue(String name) {
|
||||
Collection<String> value = toMap().get(name);
|
||||
|
||||
if (value != null) {
|
||||
return new Entry(name, value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds an attribute and its values, providing useful methods for obtaining and formatting values. Specially useful
|
||||
* for writing rule-based policies.
|
||||
*/
|
||||
class Entry {
|
||||
|
||||
private final String[] values;
|
||||
private final String name;
|
||||
|
||||
public Entry(String name, Collection<String> values) {
|
||||
this.name = name;
|
||||
this.values = values.toArray(new String[values.size()]);
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return values.length;
|
||||
}
|
||||
|
||||
public String asString(int idx) {
|
||||
if (idx >= values.length) {
|
||||
throw new IllegalArgumentException("Invalid index [" + idx + "]. Values are [" + values + "].");
|
||||
}
|
||||
|
||||
return values[idx];
|
||||
}
|
||||
|
||||
public int asInt(int idx) {
|
||||
return Integer.parseInt(asString(idx));
|
||||
}
|
||||
|
||||
public Date asDate(int idx, String pattern) {
|
||||
try {
|
||||
return new SimpleDateFormat(pattern).parse(asString(idx));
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException("Error parsing date.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public InetAddress asInetAddress(int idx) {
|
||||
try {
|
||||
return InetAddress.getByName(asString(idx));
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException("Error parsing address.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public long asLong(int idx) {
|
||||
return Long.parseLong(asString(idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes related with the representation of attributes and their manipulation.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.attribute;
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.identity;
|
||||
|
||||
import org.keycloak.authorization.attribute.Attributes;
|
||||
|
||||
/**
|
||||
* <p>Represents a security identity, which can be a person or non-person entity that was previously authenticated.
|
||||
*
|
||||
* <p>An {@link Identity} plays an important role during the evaluation of policies as they represent the entity to which one or more permissions
|
||||
* should be granted or not, providing additional information and attributes that can be relevant to the different
|
||||
* access control methods involved during the evaluation of policies.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Identity {
|
||||
|
||||
/**
|
||||
* Returns the unique identifier of this identity.
|
||||
*
|
||||
* @return the unique identifier of this identity
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the attributes or claims associated with this identity.
|
||||
*
|
||||
* @return the attributes or claims associated with this identity
|
||||
*/
|
||||
Attributes getAttributes();
|
||||
|
||||
/**
|
||||
* Indicates if this identity is granted with a role (realm or client) with the given <code>roleName</code>.
|
||||
*
|
||||
* @param roleName the name of the role
|
||||
*
|
||||
* @return true if the identity has the given role. Otherwise, it returns false.
|
||||
*/
|
||||
default boolean hasRole(String roleName) {
|
||||
return hasRealmRole(roleName) || hasClientRole(roleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this identity is granted with a realm role with the given <code>roleName</code>.
|
||||
*
|
||||
* @param roleName the name of the role
|
||||
*
|
||||
* @return true if the identity has the given role. Otherwise, it returns false.
|
||||
*/
|
||||
default boolean hasRealmRole(String roleName) {
|
||||
return getAttributes().containsValue("kc.realm.roles", roleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this identity is granted with a client role with the given <code>roleName</code>.
|
||||
*
|
||||
* @param clientId the client id
|
||||
* @param roleName the name of the role
|
||||
*
|
||||
* @return true if the identity has the given role. Otherwise, it returns false.
|
||||
*/
|
||||
default boolean hasClientRole(String clientId, String roleName) {
|
||||
return getAttributes().containsValue("kc.client." + clientId + ".roles", roleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this identity is granted with a client role with the given <code>roleName</code>.
|
||||
*
|
||||
* @param roleName the name of the role
|
||||
*
|
||||
* @return true if the identity has the given role. Otherwise, it returns false.
|
||||
*/
|
||||
default boolean hasClientRole(String roleName) {
|
||||
return getAttributes().toMap().entrySet().stream().filter(entry -> {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith("kc.client") && key.endsWith(".roles")) {
|
||||
return getAttributes().containsValue(key, roleName);
|
||||
}
|
||||
return false;
|
||||
}).findFirst().isPresent();
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes related with the representation and management of identities.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.identity;
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.model;
|
||||
|
||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||
import org.keycloak.representations.idm.authorization.Logic;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents an authorization policy and all the configuration associated with it.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Policy {
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this instance.
|
||||
*
|
||||
* @return the unique identifier for this instance
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the type of this policy.
|
||||
*
|
||||
* @return the type of this policy
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* Returns the {@link DecisionStrategy} for this policy.
|
||||
*
|
||||
* @return the decision strategy defined for this policy
|
||||
*/
|
||||
DecisionStrategy getDecisionStrategy();
|
||||
|
||||
/**
|
||||
* Sets the {DecisionStrategy} for this policy.
|
||||
*
|
||||
* @return the decision strategy for this policy
|
||||
*/
|
||||
void setDecisionStrategy(DecisionStrategy decisionStrategy);
|
||||
|
||||
/**
|
||||
* Returns the {@link Logic} for this policy.
|
||||
*
|
||||
* @return the decision strategy defined for this policy
|
||||
*/
|
||||
Logic getLogic();
|
||||
|
||||
/**
|
||||
* Sets the {Logic} for this policy.
|
||||
*
|
||||
* @return the decision strategy for this policy
|
||||
*/
|
||||
void setLogic(Logic logic);
|
||||
|
||||
/**
|
||||
* Returns a {@link Map} holding string-based key/value pairs representing any additional configuration for this policy.
|
||||
*
|
||||
* @return a map with any additional configuration defined for this policy.
|
||||
*/
|
||||
Map<String, String> getConfig();
|
||||
|
||||
/**
|
||||
* Sets a {@link Map} with string-based key/value pairs representing any additional configuration for this policy.
|
||||
*
|
||||
* @return a map with any additional configuration for this policy.
|
||||
*/
|
||||
void setConfig(Map<String, String> config);
|
||||
|
||||
/**
|
||||
* Returns the name of this policy.
|
||||
*
|
||||
* @return the name of this policy
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Sets an unique name to this policy.
|
||||
*
|
||||
* @param name an unique name
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* Returns the description of this policy.
|
||||
*
|
||||
* @return a description or null of there is no description
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Sets the description for this policy.
|
||||
*
|
||||
* @param description a description
|
||||
*/
|
||||
void setDescription(String description);
|
||||
|
||||
/**
|
||||
* Returns the {@link ResourceServer} where this policy belongs to.
|
||||
*
|
||||
* @return a resource server
|
||||
*/
|
||||
<R extends ResourceServer> R getResourceServer();
|
||||
|
||||
/**
|
||||
* Returns the {@link Policy} instances associated with this policy and used to evaluate authorization decisions when
|
||||
* this policy applies.
|
||||
*
|
||||
* @return the associated policies or an empty set if no policy is associated with this policy
|
||||
*/
|
||||
<P extends Policy> Set<P> getAssociatedPolicies();
|
||||
|
||||
/**
|
||||
* Returns the {@link Resource} instances where this policy applies.
|
||||
*
|
||||
* @return a set with all resource instances where this policy applies. Or an empty set if there is no resource associated with this policy
|
||||
*/
|
||||
<R extends Resource> Set<R> getResources();
|
||||
|
||||
/**
|
||||
* Returns the {@link Scope} instances where this policy applies.
|
||||
*
|
||||
* @return a set with all scope instances where this policy applies. Or an empty set if there is no scope associated with this policy
|
||||
*/
|
||||
<S extends Scope> Set<S> getScopes();
|
||||
|
||||
void addScope(Scope scope);
|
||||
|
||||
void removeScope(Scope scope);
|
||||
|
||||
void addAssociatedPolicy(Policy associatedPolicy);
|
||||
|
||||
void removeAssociatedPolicy(Policy associatedPolicy);
|
||||
|
||||
void addResource(Resource resource);
|
||||
|
||||
void removeResource(Resource resource);
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a resource, which is usually protected by a set of policies within a resource server.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Resource {
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this instance.
|
||||
*
|
||||
* @return the unique identifier for this instance
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the resource's name.
|
||||
*
|
||||
* @return the name of this resource
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Sets a name for this resource. The name must be unique.
|
||||
*
|
||||
* @param name the name of this resource
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* Returns a {@link java.net.URI} that uniquely identify this resource.
|
||||
*
|
||||
* @return an {@link java.net.URI} for this resource or null if not defined.
|
||||
*/
|
||||
String getUri();
|
||||
|
||||
/**
|
||||
* Sets a {@link java.net.URI} that uniquely identify this resource.
|
||||
*
|
||||
* @param uri an {@link java.net.URI} for this resource
|
||||
*/
|
||||
void setUri(String uri);
|
||||
|
||||
/**
|
||||
* Returns a string representing the type of this resource.
|
||||
*
|
||||
* @return the type of this resource or null if not defined
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* Sets a string representing the type of this resource.
|
||||
*
|
||||
* @return the type of this resource or null if not defined
|
||||
*/
|
||||
void setType(String type);
|
||||
|
||||
/**
|
||||
* Returns a {@link List} containing all the {@link Scope} associated with this resource.
|
||||
*
|
||||
* @return a list with all scopes associated with this resource
|
||||
*/
|
||||
<S extends Scope> List<S> getScopes();
|
||||
|
||||
/**
|
||||
* Returns an icon {@link java.net.URI} for this resource.
|
||||
*
|
||||
* @return a uri for an icon
|
||||
*/
|
||||
String getIconUri();
|
||||
|
||||
/**
|
||||
* Sets an icon {@link java.net.URI} for this resource.
|
||||
*
|
||||
* @return a uri for an icon
|
||||
*/
|
||||
void setIconUri(String iconUri);
|
||||
|
||||
/**
|
||||
* Returns the {@link ResourceServer} to where this resource belongs to.
|
||||
*
|
||||
* @return the resource server associated with this resource
|
||||
*/
|
||||
<R extends ResourceServer> R getResourceServer();
|
||||
|
||||
/**
|
||||
* Returns the resource's owner, which is usually an identifier that uniquely identifies the resource's owner.
|
||||
*
|
||||
* @return the owner of this resource
|
||||
*/
|
||||
String getOwner();
|
||||
|
||||
void updateScopes(Set<Scope> scopes);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.model;
|
||||
|
||||
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
|
||||
|
||||
/**
|
||||
* Represents a resource server, whose resources are managed and protected. A resource server is basically an existing
|
||||
* client application in Keycloak that will also act as a resource server.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface ResourceServer {
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this instance.
|
||||
*
|
||||
* @return the unique identifier for this instance
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the identifier of the client application (which already exists in Keycloak) that is also acting as a resource
|
||||
* server.
|
||||
*
|
||||
* @return the identifier of the client application associated with this instance.
|
||||
*/
|
||||
String getClientId();
|
||||
|
||||
/**
|
||||
* Indicates if the resource server is allowed to manage its own resources remotely using the Protection API.
|
||||
*
|
||||
* {@code true} if the resource server is allowed to managed them remotely
|
||||
*/
|
||||
boolean isAllowRemoteResourceManagement();
|
||||
|
||||
/**
|
||||
* Indicates if the resource server is allowed to manage its own resources remotely using the Protection API.
|
||||
*
|
||||
* @param allowRemoteResourceManagement {@code true} if the resource server is allowed to managed them remotely
|
||||
*/
|
||||
void setAllowRemoteResourceManagement(boolean allowRemoteResourceManagement);
|
||||
|
||||
/**
|
||||
* Returns the {@code PolicyEnforcementMode} configured for this instance.
|
||||
*
|
||||
* @return the {@code PolicyEnforcementMode} configured for this instance.
|
||||
*/
|
||||
PolicyEnforcementMode getPolicyEnforcementMode();
|
||||
|
||||
/**
|
||||
* Defines a {@code PolicyEnforcementMode} for this instance.
|
||||
*
|
||||
* @param enforcementMode one of the available options in {@code PolicyEnforcementMode}
|
||||
*/
|
||||
void setPolicyEnforcementMode(PolicyEnforcementMode enforcementMode);
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.model;
|
||||
|
||||
/**
|
||||
* Represents a scope, which is usually associated with one or more resources in order to define the actions that can be performed
|
||||
* or a specific access context.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Scope {
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this instance.
|
||||
*
|
||||
* @return the unique identifier for this instance
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the name of this scope.
|
||||
*
|
||||
* @return the name of this scope
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Sets a name for this scope. The name must be unique.
|
||||
*
|
||||
* @param name the name of this scope
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* Returns an icon {@link java.net.URI} for this scope.
|
||||
*
|
||||
* @return a uri for an icon
|
||||
*/
|
||||
String getIconUri();
|
||||
|
||||
/**
|
||||
* Sets an icon {@link java.net.URI} for this scope.
|
||||
*
|
||||
* @return a uri for an icon
|
||||
*/
|
||||
void setIconUri(String iconUri);
|
||||
|
||||
/**
|
||||
* Returns the {@link ResourceServer} instance to where this scope belongs to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ResourceServer getResourceServer();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides the domain model and any other type related with it
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.model;
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fine-grained Authorization SPI.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization;
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.permission;
|
||||
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a permission for a given resource.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class ResourcePermission {
|
||||
|
||||
private final Resource resource;
|
||||
private final List<Scope> scopes;
|
||||
private ResourceServer resourceServer;
|
||||
|
||||
public ResourcePermission(Resource resource, List<Scope> scopes, ResourceServer resourceServer) {
|
||||
this.resource = resource;
|
||||
this.scopes = scopes;
|
||||
this.resourceServer = resourceServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource to which this permission applies.
|
||||
*
|
||||
* @return the resource to which this permission applies
|
||||
*/
|
||||
public Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of permitted scopes associated with the resource
|
||||
*
|
||||
* @return a lit of permitted scopes
|
||||
*/
|
||||
public List<Scope> getScopes() {
|
||||
return Collections.unmodifiableList(this.scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource server associated with this permission.
|
||||
*
|
||||
* @return the resource server
|
||||
*/
|
||||
public ResourceServer getResourceServer() {
|
||||
return this.resourceServer;
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.permission.evaluator;
|
||||
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultPolicyEvaluator;
|
||||
import org.keycloak.authorization.policy.evaluation.EvaluationContext;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A factory for the different {@link PermissionEvaluator} implementations.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public final class Evaluators {
|
||||
|
||||
private final List<PolicyProviderFactory> policyProviderFactories;
|
||||
private final DefaultPolicyEvaluator policyEvaluator;
|
||||
private final Executor scheduler;
|
||||
|
||||
public Evaluators(List<PolicyProviderFactory> policyProviderFactories, DefaultPolicyEvaluator policyEvaluator, Executor scheduler) {
|
||||
this.policyProviderFactories = policyProviderFactories;
|
||||
this.policyEvaluator = policyEvaluator;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
public PermissionEvaluator from(List<ResourcePermission> permissions, EvaluationContext evaluationContext) {
|
||||
return schedule(permissions, evaluationContext);
|
||||
}
|
||||
|
||||
public PermissionEvaluator schedule(List<ResourcePermission> permissions, EvaluationContext evaluationContext) {
|
||||
return new ScheduledPermissionEvaluator(new IterablePermissionEvaluator(permissions.iterator(), evaluationContext, this.policyEvaluator), this.scheduler);
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.permission.evaluator;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.EvaluationContext;
|
||||
import org.keycloak.authorization.policy.evaluation.PolicyEvaluator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
class IterablePermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
private final Iterator<ResourcePermission> permissions;
|
||||
private final EvaluationContext executionContext;
|
||||
private final PolicyEvaluator policyEvaluator;
|
||||
|
||||
IterablePermissionEvaluator(Iterator<ResourcePermission> permissions, EvaluationContext executionContext, PolicyEvaluator policyEvaluator) {
|
||||
this.permissions = permissions;
|
||||
this.executionContext = executionContext;
|
||||
this.policyEvaluator = policyEvaluator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(Decision decision) {
|
||||
try {
|
||||
while (this.permissions.hasNext()) {
|
||||
this.policyEvaluator.evaluate(this.permissions.next(), this.executionContext, decision);
|
||||
}
|
||||
decision.onComplete();
|
||||
} catch (Throwable cause) {
|
||||
decision.onError(cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.permission.evaluator;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
|
||||
/**
|
||||
* An {@link PermissionEvaluator} represents a source of {@link org.keycloak.authorization.permission.ResourcePermission}, responsible for emitting these permissions
|
||||
* to a consumer in order to evaluate the authorization policies based on a {@link org.keycloak.authorization.policy.evaluation.EvaluationContext}.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PermissionEvaluator {
|
||||
|
||||
void evaluate(Decision decision);
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.permission.evaluator;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
* @see PermissionEvaluator
|
||||
*/
|
||||
class ScheduledPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
private final PermissionEvaluator publisher;
|
||||
private final Executor scheduler;
|
||||
|
||||
ScheduledPermissionEvaluator(PermissionEvaluator publisher, Executor scheduler) {
|
||||
this.publisher = publisher;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(Decision decision) {
|
||||
CompletableFuture.runAsync(() -> publisher.evaluate(decision), scheduler);
|
||||
}
|
||||
}
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public abstract class DecisionResultCollector implements Decision<DefaultEvaluation> {
|
||||
|
||||
private Map<ResourcePermission, Result> results = new HashMap();
|
||||
|
||||
@Override
|
||||
public void onDecision(DefaultEvaluation evaluation) {
|
||||
if (evaluation.getParentPolicy() != null) {
|
||||
results.computeIfAbsent(evaluation.getPermission(), Result::new).policy(evaluation.getParentPolicy()).policy(evaluation.getPolicy()).setStatus(evaluation.getEffect());
|
||||
} else {
|
||||
results.computeIfAbsent(evaluation.getPermission(), Result::new).setStatus(evaluation.getEffect());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
for (Result result : results.values()) {
|
||||
for (Result.PolicyResult policyResult : result.getResults()) {
|
||||
if (isGranted(policyResult)) {
|
||||
policyResult.setStatus(Effect.PERMIT);
|
||||
} else {
|
||||
policyResult.setStatus(Effect.DENY);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.getResults().stream()
|
||||
.filter(policyResult -> Effect.DENY.equals(policyResult.getStatus())).count() > 0) {
|
||||
result.setStatus(Effect.DENY);
|
||||
} else {
|
||||
result.setStatus(Effect.PERMIT);
|
||||
}
|
||||
}
|
||||
|
||||
onComplete(results.values().stream().collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
protected abstract void onComplete(List<Result> results);
|
||||
|
||||
private boolean isGranted(Result.PolicyResult policyResult) {
|
||||
List<Result.PolicyResult> values = policyResult.getAssociatedPolicies();
|
||||
|
||||
int grantCount = 0;
|
||||
int denyCount = policyResult.getPolicy().getAssociatedPolicies().size();
|
||||
|
||||
for (Result.PolicyResult decision : values) {
|
||||
if (decision.getStatus().equals(Effect.PERMIT)) {
|
||||
grantCount++;
|
||||
denyCount--;
|
||||
}
|
||||
}
|
||||
|
||||
Policy policy = policyResult.getPolicy();
|
||||
DecisionStrategy decisionStrategy = policy.getDecisionStrategy();
|
||||
|
||||
if (decisionStrategy == null) {
|
||||
decisionStrategy = DecisionStrategy.UNANIMOUS;
|
||||
}
|
||||
|
||||
if (DecisionStrategy.AFFIRMATIVE.equals(decisionStrategy) && grantCount > 0) {
|
||||
return true;
|
||||
} else if (DecisionStrategy.UNANIMOUS.equals(decisionStrategy) && denyCount == 0) {
|
||||
return true;
|
||||
} else if (DecisionStrategy.CONSENSUS.equals(decisionStrategy)) {
|
||||
if (grantCount > denyCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.Decision.Effect;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.representations.idm.authorization.Logic;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class DefaultEvaluation implements Evaluation {
|
||||
|
||||
private final ResourcePermission permission;
|
||||
private final EvaluationContext executionContext;
|
||||
private final Decision decision;
|
||||
private final Policy policy;
|
||||
private final Policy parentPolicy;
|
||||
private Effect effect;
|
||||
|
||||
public DefaultEvaluation(ResourcePermission permission, EvaluationContext executionContext, Policy parentPolicy, Policy policy, Decision decision) {
|
||||
this.permission = permission;
|
||||
this.executionContext = executionContext;
|
||||
this.parentPolicy = parentPolicy;
|
||||
this.policy = policy;
|
||||
this.decision = decision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ResourcePermission} to be evaluated.
|
||||
*
|
||||
* @return the permission to be evaluated
|
||||
*/
|
||||
public ResourcePermission getPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link org.keycloak.authorization.permission.evaluator.PermissionEvaluator}. Which provides access to the whole evaluation runtime context.
|
||||
*
|
||||
* @return the evaluation context
|
||||
*/
|
||||
public EvaluationContext getContext() {
|
||||
return this.executionContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants all the requested permissions to the caller.
|
||||
*/
|
||||
public void grant() {
|
||||
if (policy != null && Logic.NEGATIVE.equals(policy.getLogic())) {
|
||||
this.effect = Effect.DENY;
|
||||
} else {
|
||||
this.effect = Effect.PERMIT;
|
||||
}
|
||||
|
||||
this.decision.onDecision(this);
|
||||
}
|
||||
|
||||
public void deny() {
|
||||
if (policy != null && Logic.NEGATIVE.equals(policy.getLogic())) {
|
||||
this.effect = Effect.PERMIT;
|
||||
} else {
|
||||
this.effect = Effect.DENY;
|
||||
}
|
||||
|
||||
this.decision.onDecision(this);
|
||||
}
|
||||
|
||||
public Policy getPolicy() {
|
||||
return this.policy;
|
||||
}
|
||||
|
||||
public Policy getParentPolicy() {
|
||||
return this.parentPolicy;
|
||||
}
|
||||
|
||||
public Effect getEffect() {
|
||||
return effect;
|
||||
}
|
||||
|
||||
void denyIfNoEffect() {
|
||||
if (this.effect == null) {
|
||||
deny();
|
||||
}
|
||||
}
|
||||
}
|
||||
-189
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class DefaultPolicyEvaluator implements PolicyEvaluator {
|
||||
|
||||
private final AuthorizationProvider authorization;
|
||||
private Map<String, PolicyProviderFactory> policyProviders = new HashMap<>();
|
||||
|
||||
public DefaultPolicyEvaluator(AuthorizationProvider authorization, List<PolicyProviderFactory> policyProviderFactories) {
|
||||
this.authorization = authorization;
|
||||
|
||||
for (PolicyProviderFactory providerFactory : policyProviderFactories) {
|
||||
this.policyProviders.put(providerFactory.getId(), providerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(ResourcePermission permission, EvaluationContext executionContext, Decision decision) {
|
||||
ResourceServer resourceServer = permission.getResourceServer();
|
||||
|
||||
if (PolicyEnforcementMode.DISABLED.equals(resourceServer.getPolicyEnforcementMode())) {
|
||||
createEvaluation(permission, executionContext, decision, null, null).grant();
|
||||
return;
|
||||
}
|
||||
|
||||
StoreFactory storeFactory = this.authorization.getStoreFactory();
|
||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
||||
AtomicInteger policiesCount = new AtomicInteger(0);
|
||||
Consumer<Policy> consumer = createDecisionConsumer(permission, executionContext, decision, policiesCount);
|
||||
Resource resource = permission.getResource();
|
||||
|
||||
if (resource != null) {
|
||||
List<? extends Policy> resourcePolicies = policyStore.findByResource(resource.getId());
|
||||
|
||||
if (!resourcePolicies.isEmpty()) {
|
||||
resourcePolicies.forEach(consumer);
|
||||
}
|
||||
|
||||
if (resource.getType() != null) {
|
||||
policyStore.findByResourceType(resource.getType(), resourceServer.getId()).forEach(consumer);
|
||||
}
|
||||
|
||||
if (permission.getScopes().isEmpty() && !resource.getScopes().isEmpty()) {
|
||||
policyStore.findByScopeIds(resource.getScopes().stream().map(Scope::getId).collect(Collectors.toList()), resourceServer.getId()).forEach(consumer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!permission.getScopes().isEmpty()) {
|
||||
policyStore.findByScopeIds(permission.getScopes().stream().map(Scope::getId).collect(Collectors.toList()), resourceServer.getId()).forEach(consumer);
|
||||
}
|
||||
|
||||
if (PolicyEnforcementMode.PERMISSIVE.equals(resourceServer.getPolicyEnforcementMode()) && policiesCount.get() == 0) {
|
||||
createEvaluation(permission, executionContext, decision, null, null).grant();
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<Policy> createDecisionConsumer(ResourcePermission permission, EvaluationContext executionContext, Decision decision, AtomicInteger policiesCount) {
|
||||
return (parentPolicy) -> {
|
||||
if (hasRequestedScopes(permission, parentPolicy)) {
|
||||
for (Policy associatedPolicy : parentPolicy.getAssociatedPolicies()) {
|
||||
PolicyProviderFactory providerFactory = policyProviders.get(associatedPolicy.getType());
|
||||
|
||||
if (providerFactory == null) {
|
||||
throw new RuntimeException("Could not find a policy provider for policy type [" + associatedPolicy.getType() + "].");
|
||||
}
|
||||
|
||||
PolicyProvider policyProvider = providerFactory.create(associatedPolicy, this.authorization);
|
||||
|
||||
if (policyProvider == null) {
|
||||
throw new RuntimeException("Unknown parentPolicy provider for type [" + associatedPolicy.getType() + "].");
|
||||
}
|
||||
|
||||
DefaultEvaluation evaluation = createEvaluation(permission, executionContext, decision, parentPolicy, associatedPolicy);
|
||||
|
||||
policyProvider.evaluate(evaluation);
|
||||
evaluation.denyIfNoEffect();
|
||||
|
||||
policiesCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private DefaultEvaluation createEvaluation(ResourcePermission permission, EvaluationContext executionContext, Decision decision, Policy parentPolicy, Policy associatedPolicy) {
|
||||
return new DefaultEvaluation(permission, executionContext, parentPolicy, associatedPolicy, decision);
|
||||
}
|
||||
|
||||
private boolean hasRequestedScopes(final ResourcePermission permission, final Policy policy) {
|
||||
if (permission.getScopes().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Resource resourcePermission = permission.getResource();
|
||||
Set<Resource> policyResources = policy.getResources();
|
||||
|
||||
if (resourcePermission != null && !policyResources.isEmpty()) {
|
||||
if (!policyResources.stream().filter(resource -> resource.getId().equals(resourcePermission.getId())).findFirst().isPresent()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Set<Scope> scopes = new HashSet<>(policy.getScopes());
|
||||
|
||||
if (scopes.isEmpty()) {
|
||||
Set<Resource> resources = new HashSet<>();
|
||||
|
||||
resources.addAll(policyResources);
|
||||
|
||||
for (Resource resource : resources) {
|
||||
scopes.addAll(resource.getScopes());
|
||||
}
|
||||
|
||||
if (!resources.isEmpty() && scopes.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scopes.isEmpty()) {
|
||||
Resource resource = permission.getResource();
|
||||
String type = resource.getType();
|
||||
|
||||
if (type != null) {
|
||||
List<Resource> resourcesByType = authorization.getStoreFactory().getResourceStore().findByType(type);
|
||||
|
||||
for (Resource resourceType : resourcesByType) {
|
||||
if (resourceType.getOwner().equals(resource.getResourceServer().getClientId())) {
|
||||
resources.add(resourceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Resource resource : resources) {
|
||||
scopes.addAll(resource.getScopes());
|
||||
}
|
||||
}
|
||||
|
||||
for (Scope givenScope : scopes) {
|
||||
for (Scope scope : permission.getScopes()) {
|
||||
if (givenScope.getId().equals(scope.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
|
||||
/**
|
||||
* <p>An {@link Evaluation} is mainly used by {@link org.keycloak.authorization.policy.provider.PolicyProvider} in order to evaluate a single
|
||||
* and specific {@link ResourcePermission} against the configured policies.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Evaluation {
|
||||
|
||||
/**
|
||||
* Returns the {@link ResourcePermission} to be evaluated.
|
||||
*
|
||||
* @return the permission to be evaluated
|
||||
*/
|
||||
ResourcePermission getPermission();
|
||||
|
||||
/**
|
||||
* Returns the {@link EvaluationContext}. Which provides access to the whole evaluation runtime context.
|
||||
*
|
||||
* @return the evaluation context
|
||||
*/
|
||||
EvaluationContext getContext();
|
||||
|
||||
/**
|
||||
* Grants the requested permission to the caller.
|
||||
*/
|
||||
void grant();
|
||||
|
||||
/**
|
||||
* Denies the requested permission.
|
||||
*/
|
||||
void deny();
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.attribute.Attributes;
|
||||
import org.keycloak.authorization.identity.Identity;
|
||||
|
||||
/**
|
||||
* This interface serves as a bridge between the policy evaluation runtime and the environment in which it is running. When evaluating
|
||||
* policies, this interface can be used to query information from the execution environment/context and enrich decisions.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface EvaluationContext {
|
||||
|
||||
/**
|
||||
* Returns the {@link Identity} that represents an entity (person or non-person) to which the permissions must be granted, or not.
|
||||
*
|
||||
* @return the identity to which the permissions must be granted, or not
|
||||
*/
|
||||
Identity getIdentity();
|
||||
|
||||
/**
|
||||
* Returns all attributes within the current execution and runtime environment.
|
||||
*
|
||||
* @return the attributes within the current execution and runtime environment
|
||||
*/
|
||||
Attributes getAttributes();
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
|
||||
/**
|
||||
* <p>A {@link PolicyEvaluator} evaluates authorization policies based on a given {@link ResourcePermission}, sending
|
||||
* the results to a {@link Decision} point through the methods defined in that interface.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PolicyEvaluator {
|
||||
|
||||
/**
|
||||
* Starts the evaluation of the configured authorization policies.
|
||||
*
|
||||
* @param decision a {@link Decision} point to where notifications events will be delivered during the evaluation
|
||||
*/
|
||||
void evaluate(ResourcePermission permission, EvaluationContext executionContext, Decision decision);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.Decision.Effect;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class Result {
|
||||
|
||||
private final ResourcePermission permission;
|
||||
private List<PolicyResult> results = new ArrayList<>();
|
||||
private Effect status;
|
||||
|
||||
public Result(ResourcePermission permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public ResourcePermission getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public List<PolicyResult> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public PolicyResult policy(Policy policy) {
|
||||
for (PolicyResult result : this.results) {
|
||||
if (result.getPolicy().equals(policy)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
PolicyResult policyResult = new PolicyResult(policy);
|
||||
|
||||
this.results.add(policyResult);
|
||||
|
||||
return policyResult;
|
||||
}
|
||||
|
||||
public void setStatus(final Effect status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Effect getEffect() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static class PolicyResult {
|
||||
|
||||
private final Policy policy;
|
||||
private List<PolicyResult> associatedPolicies = new ArrayList<>();
|
||||
private Effect status;
|
||||
|
||||
public PolicyResult(Policy policy) {
|
||||
this.policy = policy;
|
||||
}
|
||||
|
||||
public PolicyResult status(Effect status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PolicyResult policy(Policy policy) {
|
||||
return getPolicy(policy, this.associatedPolicies);
|
||||
}
|
||||
|
||||
private PolicyResult getPolicy(Policy policy, List<PolicyResult> results) {
|
||||
for (PolicyResult result : results) {
|
||||
if (result.getPolicy().equals(policy)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
PolicyResult policyResult = new PolicyResult(policy);
|
||||
|
||||
results.add(policyResult);
|
||||
|
||||
return policyResult;
|
||||
}
|
||||
|
||||
public Policy getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
|
||||
public List<PolicyResult> getAssociatedPolicies() {
|
||||
return associatedPolicies;
|
||||
}
|
||||
|
||||
public Effect getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(final Effect status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes related with the evaluation of policies.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.policy.evaluation;
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.provider;
|
||||
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PolicyProvider extends Provider {
|
||||
|
||||
void evaluate(Evaluation evaluation);
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.provider;
|
||||
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PolicyProviderAdminService {
|
||||
|
||||
void onCreate(Policy policy);
|
||||
|
||||
void onUpdate(Policy policy);
|
||||
|
||||
void onRemove(Policy policy);
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.provider;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PolicyProviderFactory extends ProviderFactory<PolicyProvider> {
|
||||
|
||||
String getName();
|
||||
|
||||
String getGroup();
|
||||
|
||||
PolicyProvider create(Policy policy, AuthorizationProvider authorization);
|
||||
|
||||
PolicyProviderAdminService getAdminResource(ResourceServer resourceServer);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.policy.provider;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class PolicySpi implements Spi {
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "policy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return PolicyProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return PolicyProviderFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes and a SPI to plug different policy providers.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.policy.provider;
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
import org.keycloak.authorization.store.syncronization.ClientApplicationSynchronizer;
|
||||
import org.keycloak.authorization.store.syncronization.RealmSynchronizer;
|
||||
import org.keycloak.authorization.store.syncronization.Synchronizer;
|
||||
import org.keycloak.authorization.store.syncronization.UserSynchronizer;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel.ClientRemovedEvent;
|
||||
import org.keycloak.models.RealmModel.RealmRemovedEvent;
|
||||
import org.keycloak.models.UserModel.UserRemovedEvent;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface AuthorizationStoreFactory extends ProviderFactory<StoreFactory> {
|
||||
|
||||
@Override
|
||||
default void postInit(KeycloakSessionFactory factory) {
|
||||
registerSynchronizationListeners(factory);
|
||||
}
|
||||
|
||||
default void registerSynchronizationListeners(KeycloakSessionFactory factory) {
|
||||
Map<Class<? extends ProviderEvent>, Synchronizer> synchronizers = new HashMap<>();
|
||||
|
||||
synchronizers.put(ClientRemovedEvent.class, new ClientApplicationSynchronizer());
|
||||
synchronizers.put(RealmRemovedEvent.class, new RealmSynchronizer());
|
||||
synchronizers.put(UserRemovedEvent.class, new UserSynchronizer());
|
||||
|
||||
factory.register(event -> {
|
||||
try {
|
||||
synchronizers.forEach((eventType, synchronizer) -> {
|
||||
if (eventType.isInstance(event)) {
|
||||
synchronizer.synchronize(event, factory);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error synchronizing authorization data.", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link PolicyStore} is responsible to manage the persistence of {@link Policy} instances.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface PolicyStore {
|
||||
|
||||
/**
|
||||
* Creates a new {@link Policy} instance. The new instance is not necessarily persisted though, which may require
|
||||
* a call to the {#save} method to actually make it persistent.
|
||||
*
|
||||
* @param name the name of the policy
|
||||
* @param type the type of the policy
|
||||
* @param resourceServer the resource server to which this policy belongs
|
||||
* @return a new instance of {@link Policy}
|
||||
*/
|
||||
Policy create(String name, String type, ResourceServer resourceServer);
|
||||
|
||||
/**
|
||||
* Deletes a policy from the underlying persistence mechanism.
|
||||
*
|
||||
* @param id the id of the policy to delete
|
||||
*/
|
||||
void delete(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link Policy} with the given <code>id</code>
|
||||
*
|
||||
* @param id the identifier of the policy
|
||||
* @return a policy with the given identifier.
|
||||
*/
|
||||
Policy findById(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link Policy} with the given <code>name</code>
|
||||
*
|
||||
* @param name the name of the policy
|
||||
* @param resourceServerId the resource server id
|
||||
* @return a policy with the given name.
|
||||
*/
|
||||
Policy findByName(String name, String resourceServerId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} associated with a {@link ResourceServer} with the given <code>resourceServerId</code>.
|
||||
*
|
||||
* @param resourceServerId the identifier of a resource server
|
||||
* @return a list of policies that belong to the given resource server
|
||||
*/
|
||||
List<Policy> findByResourceServer(String resourceServerId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} associated with a {@link ResourceServer} with the given <code>resourceServerId</code>.
|
||||
*
|
||||
* @param attributes a map holding the attributes that will be used as a filter
|
||||
* @param resourceServerId the identifier of a resource server
|
||||
* @return a list of policies that belong to the given resource server
|
||||
*/
|
||||
List<Policy> findByResourceServer(Map<String, String[]> attributes, String resourceServerId, int firstResult, int maxResult);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.core.model.Resource} with the given <code>resourceId</code>.
|
||||
*
|
||||
* @param resourceId the identifier of a resource
|
||||
* @return a list of policies associated with the given resource
|
||||
*/
|
||||
List<Policy> findByResource(String resourceId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.core.model.Resource} with the given <code>type</code>.
|
||||
*
|
||||
* @param resourceType the type of a resource
|
||||
* @param resourceServerId the resource server id
|
||||
* @return a list of policies associated with the given resource type
|
||||
*/
|
||||
List<Policy> findByResourceType(String resourceType, String resourceServerId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.core.model.Scope} with the given <code>scopeIds</code>.
|
||||
*
|
||||
* @param scopeIds the id of the scopes
|
||||
* @param resourceServerId the resource server id
|
||||
* @return a list of policies associated with the given scopes
|
||||
*/
|
||||
List<Policy> findByScopeIds(List<String> scopeIds, String resourceServerId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} with the given <code>type</code>.
|
||||
*
|
||||
* @param type the type of the policy
|
||||
* @return a list of policies with the given type
|
||||
*/
|
||||
List<Policy> findByType(String type);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Policy} that depends on another policy with the given <code>id</code>.
|
||||
*
|
||||
* @param id the id of the policy to query its dependents
|
||||
* @return a list of policies that depends on the a policy with the given identifier
|
||||
*/
|
||||
List<Policy> findDependentPolicies(String id);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
|
||||
/**
|
||||
* A {@link ResourceServerStore} is responsible to manage the persistence of {@link ResourceServer} instances.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface ResourceServerStore {
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link ResourceServer} instance backed by this persistent storage implementation.
|
||||
*
|
||||
* @param clientId the client id acting as a resource server
|
||||
*
|
||||
* @return an instance backed by the underlying storage implementation
|
||||
*/
|
||||
ResourceServer create(String clientId);
|
||||
|
||||
/**
|
||||
* Removes a {@link ResourceServer} instance, with the given {@code id} from the persistent storage.
|
||||
*
|
||||
* @param id the identifier of an existing resource server instance
|
||||
*/
|
||||
void delete(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link ResourceServer} instance based on its identifier.
|
||||
*
|
||||
* @param id the identifier of an existing resource server instance
|
||||
*
|
||||
* @return the resource server instance with the given identifier or null if no instance was found
|
||||
*/
|
||||
ResourceServer findById(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link ResourceServer} instance based on the identifier of a client application.
|
||||
*
|
||||
* @param id the identifier of an existing client application
|
||||
*
|
||||
* @return the resource server instance, with the given client id or null if no instance was found
|
||||
*/
|
||||
ResourceServer findByClient(String id);
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link ResourceStore} is responsible to manage the persistence of {@link Resource} instances.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface ResourceStore {
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link Resource} instance backed by this persistent storage implementation.
|
||||
*
|
||||
* @param name the name of this resource. It must be unique.
|
||||
* @param resourceServer the resource server to where the given resource belongs to
|
||||
* @param owner the owner of this resource or null if the resource server is the owner
|
||||
* @return an instance backed by the underlying storage implementation
|
||||
*/
|
||||
Resource create(String name, ResourceServer resourceServer, String owner);
|
||||
|
||||
/**
|
||||
* Removes a {@link Resource} instance, with the given {@code id} from the persistent storage.
|
||||
*
|
||||
* @param id the identifier of an existing resource instance
|
||||
*/
|
||||
void delete(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link Resource} instance based on its identifier.
|
||||
*
|
||||
* @param id the identifier of an existing resource instance
|
||||
* @return the resource instance with the given identifier or null if no instance was found
|
||||
*/
|
||||
Resource findById(String id);
|
||||
|
||||
/**
|
||||
* Finds all {@link Resource} instances with the given {@code ownerId}.
|
||||
*
|
||||
* @param ownerId the identifier of the owner
|
||||
* @return a list with all resource instances owned by the given owner
|
||||
*/
|
||||
List<Resource> findByOwner(String ownerId);
|
||||
|
||||
/**
|
||||
* Finds all {@link Resource} instances associated with a given resource server.
|
||||
*
|
||||
* @param resourceServerId the identifier of the resource server
|
||||
* @return a list with all resources associated with the given resource server
|
||||
*/
|
||||
List<Resource> findByResourceServer(String resourceServerId);
|
||||
|
||||
/**
|
||||
* Finds all {@link Resource} instances associated with a given resource server.
|
||||
*
|
||||
* @param attributes a map holding the attributes that will be used as a filter
|
||||
* @param resourceServerId the identifier of the resource server
|
||||
* @return a list with all resources associated with the given resource server
|
||||
*/
|
||||
List<Resource> findByResourceServer(Map<String, String[]> attributes, String resourceServerId, int firstResult, int maxResult);
|
||||
|
||||
/**
|
||||
* Finds all {@link Resource} associated with a given scope.
|
||||
*
|
||||
* @param id one or more scope identifiers
|
||||
* @return a list of resources associated with the given scope(s)
|
||||
*/
|
||||
List<Resource> findByScope(String... id);
|
||||
|
||||
/**
|
||||
* Find a {@link Resource} by its name.
|
||||
*
|
||||
* @param name the name of the resource
|
||||
* @param resourceServerId the identifier of the resource server
|
||||
* @return a resource with the given name
|
||||
*/
|
||||
Resource findByName(String name, String resourceServerId);
|
||||
|
||||
/**
|
||||
* Finds all {@link Resource} with the given type.
|
||||
*
|
||||
* @param type the type of the resource
|
||||
* @return a list of resources with the given type
|
||||
*/
|
||||
List<Resource> findByType(String type);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link ScopeStore} is responsible to manage the persistence of {@link Scope} instances.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface ScopeStore {
|
||||
|
||||
/**
|
||||
* Creates a new {@link Scope} instance. The new instance is not necessarily persisted though, which may require
|
||||
* a call to the {#save} method to actually make it persistent.
|
||||
*
|
||||
* @param name the name of the scope
|
||||
* @param resourceServer the resource server to which this scope belongs
|
||||
*
|
||||
* @return a new instance of {@link Scope}
|
||||
*/
|
||||
Scope create(String name, ResourceServer resourceServer);
|
||||
|
||||
/**
|
||||
* Deletes a scope from the underlying persistence mechanism.
|
||||
*
|
||||
* @param id the id of the scope to delete
|
||||
*/
|
||||
void delete(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link Scope} with the given <code>id</code>
|
||||
*
|
||||
* @param id the identifier of the scope
|
||||
*
|
||||
* @return a scope with the given identifier.
|
||||
*/
|
||||
Scope findById(String id);
|
||||
|
||||
/**
|
||||
* Returns a {@link Scope} with the given <code>name</code>
|
||||
*
|
||||
* @param name the name of the scope
|
||||
*
|
||||
* @param resourceServerId
|
||||
* @return a scope with the given name.
|
||||
*/
|
||||
Scope findByName(String name, String resourceServerId);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Scope} associated with a {@link ResourceServer} with the given <code>resourceServerId</code>.
|
||||
*
|
||||
* @param resourceServerId the identifier of a resource server
|
||||
*
|
||||
* @return a list of scopes that belong to the given resource server
|
||||
*/
|
||||
List<Scope> findByResourceServer(String id);
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Scope} associated with a {@link ResourceServer} with the given <code>resourceServerId</code>.
|
||||
*
|
||||
* @param attributes a map holding the attributes that will be used as a filter
|
||||
* @param resourceServerId the identifier of a resource server
|
||||
*
|
||||
* @return a list of scopes that belong to the given resource server
|
||||
*/
|
||||
List<Scope> findByResourceServer(Map<String, String[]> attributes, String resourceServerId, int firstResult, int maxResult);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* <p>A factory for the different types of storages that manage the persistence of the domain model types.
|
||||
*
|
||||
* <p>Implementations of this interface are usually related with the creation of those storage types accordingly with a
|
||||
* specific persistence mechanism such as relational and NoSQL databases, filesystem, etc.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface StoreFactory extends Provider {
|
||||
|
||||
/**
|
||||
* Returns a {@link ResourceStore}.
|
||||
*
|
||||
* @return the resource store
|
||||
*/
|
||||
ResourceStore getResourceStore();
|
||||
|
||||
/**
|
||||
* Returns a {@link ResourceServerStore}.
|
||||
*
|
||||
* @return the resource server store
|
||||
*/
|
||||
ResourceServerStore getResourceServerStore();
|
||||
|
||||
/**
|
||||
* Returns a {@link ScopeStore}.
|
||||
*
|
||||
* @return the scope store
|
||||
*/
|
||||
ScopeStore getScopeStore();
|
||||
|
||||
/**
|
||||
* Returns a {@link PolicyStore}.
|
||||
*
|
||||
* @return the policy store
|
||||
*/
|
||||
PolicyStore getPolicyStore();
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class StoreFactorySpi implements Spi {
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "authorizationPersister";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return StoreFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return AuthorizationStoreFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes and a SPI to plug different metadata storage implementations.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
package org.keycloak.authorization.store;
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store.syncronization;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.store.ResourceServerStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel.ClientRemovedEvent;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class ClientApplicationSynchronizer implements Synchronizer<ClientRemovedEvent> {
|
||||
|
||||
@Override
|
||||
public void synchronize(ClientRemovedEvent event, KeycloakSessionFactory factory) {
|
||||
ProviderFactory<AuthorizationProvider> providerFactory = factory.getProviderFactory(AuthorizationProvider.class);
|
||||
AuthorizationProvider authorizationProvider = providerFactory.create(event.getKeycloakSession());
|
||||
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
|
||||
ResourceServerStore store = storeFactory.getResourceServerStore();
|
||||
ResourceServer resourceServer = store.findByClient(event.getClient().getId());
|
||||
|
||||
if (resourceServer != null) {
|
||||
String id = resourceServer.getId();
|
||||
storeFactory.getResourceStore().findByResourceServer(id).forEach(resource -> storeFactory.getResourceStore().delete(resource.getId()));
|
||||
storeFactory.getScopeStore().findByResourceServer(id).forEach(scope -> storeFactory.getScopeStore().delete(scope.getId()));
|
||||
storeFactory.getPolicyStore().findByResourceServer(id).forEach(scope -> storeFactory.getPolicyStore().delete(scope.getId()));
|
||||
storeFactory.getResourceServerStore().delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store.syncronization;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel.RealmRemovedEvent;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class RealmSynchronizer implements Synchronizer<RealmRemovedEvent> {
|
||||
@Override
|
||||
public void synchronize(RealmRemovedEvent event, KeycloakSessionFactory factory) {
|
||||
ProviderFactory<AuthorizationProvider> providerFactory = factory.getProviderFactory(AuthorizationProvider.class);
|
||||
AuthorizationProvider authorizationProvider = providerFactory.create(event.getKeycloakSession());
|
||||
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
|
||||
|
||||
event.getRealm().getClients().forEach(clientModel -> {
|
||||
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel.getClientId());
|
||||
|
||||
if (resourceServer != null) {
|
||||
String id = resourceServer.getId();
|
||||
storeFactory.getResourceStore().findByResourceServer(id).forEach(resource -> storeFactory.getResourceStore().delete(resource.getId()));
|
||||
storeFactory.getScopeStore().findByResourceServer(id).forEach(scope -> storeFactory.getScopeStore().delete(scope.getId()));
|
||||
storeFactory.getPolicyStore().findByResourceServer(id).forEach(scope -> storeFactory.getPolicyStore().delete(scope.getId()));
|
||||
storeFactory.getResourceServerStore().delete(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2016 Red Hat, Inc., and individual 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.authorization.store.syncronization;
|
||||
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public interface Synchronizer<E extends ProviderEvent> {
|
||||
|
||||
void synchronize(E event, KeycloakSessionFactory factory);
|
||||
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.authorization.store.syncronization;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserModel.UserRemovedEvent;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class UserSynchronizer implements Synchronizer<UserRemovedEvent> {
|
||||
|
||||
@Override
|
||||
public void synchronize(UserRemovedEvent event, KeycloakSessionFactory factory) {
|
||||
ProviderFactory<AuthorizationProvider> providerFactory = factory.getProviderFactory(AuthorizationProvider.class);
|
||||
AuthorizationProvider authorizationProvider = providerFactory.create(event.getKeycloakSession());
|
||||
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
|
||||
UserModel userModel = event.getUser();
|
||||
ResourceStore resourceStore = storeFactory.getResourceStore();
|
||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
||||
|
||||
resourceStore.findByOwner(userModel.getId()).forEach(resource -> {
|
||||
String resourceId = resource.getId();
|
||||
policyStore.findByResource(resourceId).forEach(policy -> {
|
||||
if (policy.getResources().size() == 1) {
|
||||
policyStore.delete(policy.getId());
|
||||
} else {
|
||||
policy.removeResource(resource);
|
||||
}
|
||||
});
|
||||
resourceStore.delete(resourceId);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* 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.events.EventBuilder;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public abstract class AbstractIdentityProvider<C extends IdentityProviderModel> implements IdentityProvider<C> {
|
||||
|
||||
protected final KeycloakSession session;
|
||||
private final C config;
|
||||
|
||||
public AbstractIdentityProvider(KeycloakSession session, C config) {
|
||||
this.session = session;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public C getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response export(UriInfo uriInfo, RealmModel realm, String format) {
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object callback(RealmModel realm, AuthenticationCallback callback, EventBuilder event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response performLogin(AuthenticationRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response keycloakInitiatedBrowserLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backchannelLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachUserSession(UserSessionModel userSession, ClientSessionModel clientSession, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityProviderDataMarshaller getMarshaller() {
|
||||
return new DefaultDataMarshaller();
|
||||
}
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public abstract class AbstractIdentityProviderFactory<T extends IdentityProvider> implements IdentityProviderFactory<T> {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create(KeycloakSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> parseConfig(KeycloakSession session, InputStream inputStream) {
|
||||
return new HashMap<String, String>();
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.IdentityProviderMapperModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public abstract class AbstractIdentityProviderMapper implements IdentityProviderMapper {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityProviderMapper create(KeycloakSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(org.keycloak.Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* 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.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public class AuthenticationRequest {
|
||||
|
||||
private final KeycloakSession session;
|
||||
private final UriInfo uriInfo;
|
||||
private final String state;
|
||||
private final HttpRequest httpRequest;
|
||||
private final RealmModel realm;
|
||||
private final String redirectUri;
|
||||
private final ClientSessionModel clientSession;
|
||||
|
||||
public AuthenticationRequest(KeycloakSession session, RealmModel realm, ClientSessionModel clientSession, HttpRequest httpRequest, UriInfo uriInfo, String state, String redirectUri) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.httpRequest = httpRequest;
|
||||
this.uriInfo = uriInfo;
|
||||
this.state = state;
|
||||
this.redirectUri = redirectUri;
|
||||
this.clientSession = clientSession;
|
||||
}
|
||||
|
||||
public KeycloakSession getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public UriInfo getUriInfo() {
|
||||
return this.uriInfo;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public HttpRequest getHttpRequest() {
|
||||
return this.httpRequest;
|
||||
}
|
||||
|
||||
public RealmModel getRealm() {
|
||||
return this.realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the redirect url that must be included in an authentication request in order to process responses from an
|
||||
* identity provider.</p>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getRedirectUri() {
|
||||
return this.redirectUri;
|
||||
}
|
||||
|
||||
public ClientSessionModel getClientSession() {
|
||||
return this.clientSession;
|
||||
}
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* 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.ClientSessionModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>Represents all identity information obtained from an {@link org.keycloak.broker.provider.IdentityProvider} after a
|
||||
* successful authentication.</p>
|
||||
*
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public class BrokeredIdentityContext {
|
||||
|
||||
private String id;
|
||||
private String username;
|
||||
private String modelUsername;
|
||||
private String email;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String brokerSessionId;
|
||||
private String brokerUserId;
|
||||
private String code;
|
||||
private String token;
|
||||
private IdentityProviderModel idpConfig;
|
||||
private IdentityProvider idp;
|
||||
private Map<String, Object> contextData = new HashMap<>();
|
||||
private ClientSessionModel clientSession;
|
||||
|
||||
public BrokeredIdentityContext(String id) {
|
||||
if (id == null) {
|
||||
throw new RuntimeException("No identifier provider for identity.");
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Username in remote idp
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* username to store in UserModel
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getModelUsername() {
|
||||
return modelUsername;
|
||||
}
|
||||
|
||||
public void setModelUsername(String modelUsername) {
|
||||
this.modelUsername = modelUsername;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getBrokerSessionId() {
|
||||
return brokerSessionId;
|
||||
}
|
||||
|
||||
public void setBrokerSessionId(String brokerSessionId) {
|
||||
this.brokerSessionId = brokerSessionId;
|
||||
}
|
||||
|
||||
public String getBrokerUserId() {
|
||||
return brokerUserId;
|
||||
}
|
||||
|
||||
public void setBrokerUserId(String brokerUserId) {
|
||||
this.brokerUserId = brokerUserId;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public IdentityProviderModel getIdpConfig() {
|
||||
return idpConfig;
|
||||
}
|
||||
|
||||
public void setIdpConfig(IdentityProviderModel idpConfig) {
|
||||
this.idpConfig = idpConfig;
|
||||
}
|
||||
|
||||
public IdentityProvider getIdp() {
|
||||
return idp;
|
||||
}
|
||||
|
||||
public void setIdp(IdentityProvider idp) {
|
||||
this.idp = idp;
|
||||
}
|
||||
|
||||
public Map<String, Object> getContextData() {
|
||||
return contextData;
|
||||
}
|
||||
|
||||
public void setContextData(Map<String, Object> contextData) {
|
||||
this.contextData = contextData;
|
||||
}
|
||||
|
||||
// Set the attribute, which will be available on "Update profile" page and in authenticators
|
||||
public void setUserAttribute(String attributeName, String attributeValue) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(attributeValue);
|
||||
getContextData().put(Constants.USER_ATTRIBUTES_PREFIX + attributeName, list);
|
||||
}
|
||||
|
||||
public String getUserAttribute(String attributeName) {
|
||||
List<String> userAttribute = (List<String>) getContextData().get(Constants.USER_ATTRIBUTES_PREFIX + attributeName);
|
||||
if (userAttribute == null || userAttribute.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return userAttribute.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public ClientSessionModel getClientSession() {
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
public void setClientSession(ClientSessionModel clientSession) {
|
||||
this.clientSession = clientSession;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
if (name != null) {
|
||||
int i = name.lastIndexOf(' ');
|
||||
if (i != -1) {
|
||||
firstName = name.substring(0, i);
|
||||
lastName = name.substring(i + 1);
|
||||
} else {
|
||||
firstName = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"id='" + id + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ConfigConstants {
|
||||
String ROLE = "role";
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.common.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class DefaultDataMarshaller implements IdentityProviderDataMarshaller {
|
||||
|
||||
@Override
|
||||
public String serialize(Object value) {
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
} else {
|
||||
try {
|
||||
byte[] bytes = JsonSerialization.writeValueAsBytes(value);
|
||||
return Base64Url.encode(bytes);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T deserialize(String serialized, Class<T> clazz) {
|
||||
try {
|
||||
if (clazz.equals(String.class)) {
|
||||
return clazz.cast(serialized);
|
||||
} else {
|
||||
byte[] bytes = Base64Url.decode(serialized);
|
||||
if (List.class.isAssignableFrom(clazz)) {
|
||||
List list = JsonSerialization.readValue(bytes, List.class);
|
||||
return clazz.cast(list);
|
||||
} else {
|
||||
return JsonSerialization.readValue(bytes, clazz);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author pedroigor
|
||||
*/
|
||||
public class IdentityBrokerException extends RuntimeException {
|
||||
|
||||
public IdentityBrokerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public IdentityBrokerException(String message, Throwable t) {
|
||||
super(message, t);
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* 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.events.EventBuilder;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public interface IdentityProvider<C extends IdentityProviderModel> extends Provider {
|
||||
|
||||
interface AuthenticationCallback {
|
||||
/**
|
||||
* This method should be called by provider after the JAXRS callback endpoint has finished authentication
|
||||
* with the remote IDP
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
Response authenticated(BrokeredIdentityContext context);
|
||||
|
||||
Response cancelled(String code);
|
||||
|
||||
Response error(String code, String message);
|
||||
}
|
||||
|
||||
|
||||
void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, BrokeredIdentityContext context);
|
||||
void attachUserSession(UserSessionModel userSession, ClientSessionModel clientSession, BrokeredIdentityContext context);
|
||||
void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context);
|
||||
void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context);
|
||||
|
||||
/**
|
||||
* JAXRS callback endpoint for when the remote IDP wants to callback to keycloak.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object callback(RealmModel realm, AuthenticationCallback callback, EventBuilder event);
|
||||
|
||||
/**
|
||||
* <p>Initiates the authentication process by sending an authentication request to an identity provider. This method is called
|
||||
* only once during the authentication.</p>
|
||||
*
|
||||
* @param request The initial authentication request. Contains all the contextual information in order to build an authentication request to the
|
||||
* identity provider.
|
||||
* @return
|
||||
*/
|
||||
Response performLogin(AuthenticationRequest request);
|
||||
|
||||
/**
|
||||
* <p>Returns a {@link javax.ws.rs.core.Response} containing the token previously stored during the authentication process for a
|
||||
* specific user.</p>
|
||||
*
|
||||
* @param identity
|
||||
* @return
|
||||
*/
|
||||
Response retrieveToken(KeycloakSession session, FederatedIdentityModel identity);
|
||||
|
||||
void backchannelLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Called when a Keycloak application initiates a logout through the browser. This is expected to do a logout
|
||||
* with the IDP
|
||||
*
|
||||
* @param userSession
|
||||
* @param uriInfo
|
||||
* @param realm
|
||||
* @return null if this is not supported by this provider
|
||||
*/
|
||||
Response keycloakInitiatedBrowserLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Export a representation of the IdentityProvider in a specific format. For example, a SAML EntityDescriptor
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Response export(UriInfo uriInfo, RealmModel realm, String format);
|
||||
|
||||
/**
|
||||
* Implementation of marshaller to serialize/deserialize attached data to Strings, which can be saved in clientSession
|
||||
* @return
|
||||
*/
|
||||
IdentityProviderDataMarshaller getMarshaller();
|
||||
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface IdentityProviderDataMarshaller {
|
||||
|
||||
String serialize(Object obj);
|
||||
<T> T deserialize(String serialized, Class<T> clazz);
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public interface IdentityProviderFactory<T extends IdentityProvider> extends ProviderFactory<T> {
|
||||
|
||||
/**
|
||||
* <p>A friendly name for this factory.</p>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* <p>Creates an {@link IdentityProvider} based on the configuration contained in
|
||||
* <code>model</code>.</p>
|
||||
*
|
||||
* @param session
|
||||
* @param model The configuration to be used to create the identity provider.
|
||||
* @return
|
||||
*/
|
||||
T create(KeycloakSession session, IdentityProviderModel model);
|
||||
|
||||
/**
|
||||
* <p>Creates an {@link IdentityProvider} based on the configuration from
|
||||
* <code>inputStream</code>.</p>
|
||||
*
|
||||
* @param session
|
||||
* @param inputStream The input stream from where configuration will be loaded from..
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> parseConfig(KeycloakSession session, InputStream inputStream);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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.IdentityProviderMapperModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.ConfiguredProvider;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface IdentityProviderMapper extends Provider, ProviderFactory<IdentityProviderMapper>,ConfiguredProvider {
|
||||
public static final String ANY_PROVIDER = "*";
|
||||
|
||||
String[] getCompatibleProviders();
|
||||
String getDisplayCategory();
|
||||
String getDisplayType();
|
||||
|
||||
/**
|
||||
* Called to determine what keycloak username and email to use to process the login request from the external IDP.
|
||||
* It's called before "FirstBrokerLogin" flow, so can be used to map attributes to BrokeredIdentityContext ( BrokeredIdentityContext.setUserAttribute ),
|
||||
* which will be available on "Review Profile" page and in authenticators during FirstBrokerLogin flow
|
||||
*
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param mapperModel
|
||||
* @param context
|
||||
*/
|
||||
void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context);
|
||||
|
||||
/**
|
||||
* Called after UserModel is created for first time for this user. Called after "FirstBrokerLogin" flow
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param user
|
||||
* @param mapperModel
|
||||
* @param context
|
||||
*/
|
||||
void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context);
|
||||
|
||||
/**
|
||||
* Called when this user has logged in before and has already been imported.
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param user
|
||||
* @param mapperModel
|
||||
* @param context
|
||||
*/
|
||||
void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class IdentityProviderMapperSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "identity-provider-mapper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return IdentityProviderMapper.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return IdentityProviderMapper.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public class IdentityProviderSpi implements Spi {
|
||||
|
||||
public static final String IDENTITY_PROVIDER_SPI_NAME = "identity_provider";
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return IDENTITY_PROVIDER_SPI_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return IdentityProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return IdentityProviderFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
* @author Vlastimil Elias (velias at redhat dot com)
|
||||
*/
|
||||
public class SimpleHttp {
|
||||
|
||||
|
||||
private String url;
|
||||
private String method;
|
||||
private Map<String, String> headers;
|
||||
private Map<String, String> params;
|
||||
|
||||
private SSLSocketFactory sslFactory;
|
||||
private HostnameVerifier hostnameVerifier;
|
||||
|
||||
protected SimpleHttp(String url, String method) {
|
||||
this.url = url;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public static SimpleHttp doGet(String url) {
|
||||
return new SimpleHttp(url, "GET");
|
||||
}
|
||||
|
||||
public static SimpleHttp doPost(String url) {
|
||||
return new SimpleHttp(url, "POST");
|
||||
}
|
||||
|
||||
public SimpleHttp header(String name, String value) {
|
||||
if (headers == null) {
|
||||
headers = new HashMap<String, String>();
|
||||
}
|
||||
headers.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleHttp param(String name, String value) {
|
||||
if (params == null) {
|
||||
params = new HashMap<String, String>();
|
||||
}
|
||||
params.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleHttp sslFactory(SSLSocketFactory factory) {
|
||||
sslFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleHttp hostnameVerifier(HostnameVerifier verifier) {
|
||||
hostnameVerifier = verifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String asString() throws IOException {
|
||||
boolean get = method.equals("GET");
|
||||
boolean post = method.equals("POST");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (get) {
|
||||
sb.append(url);
|
||||
}
|
||||
|
||||
if (params != null) {
|
||||
boolean f = true;
|
||||
for (Map.Entry<String, String> p : params.entrySet()) {
|
||||
if (f) {
|
||||
f = false;
|
||||
if (get) {
|
||||
sb.append("?");
|
||||
}
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(URLEncoder.encode(p.getKey(), "UTF-8"));
|
||||
sb.append("=");
|
||||
sb.append(URLEncoder.encode(p.getValue(), "UTF-8"));
|
||||
}
|
||||
}
|
||||
|
||||
if (get) {
|
||||
url = sb.toString();
|
||||
}
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
setupTruststoreIfApplicable(connection);
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
|
||||
try {
|
||||
connection.setRequestMethod(method);
|
||||
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> h : headers.entrySet()) {
|
||||
connection.setRequestProperty(h.getKey(), h.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (post) {
|
||||
String data = sb.toString();
|
||||
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
connection.setRequestProperty("Content-Length", String.valueOf(data.length()));
|
||||
|
||||
os = connection.getOutputStream();
|
||||
os.write(data.getBytes());
|
||||
} else {
|
||||
connection.setDoOutput(false);
|
||||
}
|
||||
|
||||
String ce = connection.getHeaderField("Content-Encoding");
|
||||
is = connection.getInputStream();
|
||||
if ("gzip".equals(ce)) {
|
||||
is = new GZIPInputStream(is);
|
||||
}
|
||||
return toString(is);
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.disconnect();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int asStatus() throws IOException {
|
||||
boolean get = method.equals("GET");
|
||||
boolean post = method.equals("POST");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (get) {
|
||||
sb.append(url);
|
||||
}
|
||||
|
||||
if (params != null) {
|
||||
boolean f = true;
|
||||
for (Map.Entry<String, String> p : params.entrySet()) {
|
||||
if (f) {
|
||||
f = false;
|
||||
if (get) {
|
||||
sb.append("?");
|
||||
}
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(URLEncoder.encode(p.getKey(), "UTF-8"));
|
||||
sb.append("=");
|
||||
sb.append(URLEncoder.encode(p.getValue(), "UTF-8"));
|
||||
}
|
||||
}
|
||||
|
||||
if (get) {
|
||||
url = sb.toString();
|
||||
}
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
setupTruststoreIfApplicable(connection);
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
|
||||
try {
|
||||
connection.setRequestMethod(method);
|
||||
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> h : headers.entrySet()) {
|
||||
connection.setRequestProperty(h.getKey(), h.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (post) {
|
||||
String data = sb.toString();
|
||||
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
connection.setRequestProperty("Content-Length", String.valueOf(data.length()));
|
||||
|
||||
os = connection.getOutputStream();
|
||||
os.write(data.getBytes());
|
||||
} else {
|
||||
connection.setDoOutput(false);
|
||||
}
|
||||
|
||||
is = connection.getInputStream();
|
||||
return connection.getResponseCode();
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.disconnect();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String toString(InputStream is) throws IOException {
|
||||
InputStreamReader reader = new InputStreamReader(is);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
char[] buffer = new char[1024 * 4];
|
||||
for (int n = reader.read(buffer); n != -1; n = reader.read(buffer)) {
|
||||
writer.write(buffer, 0, n);
|
||||
}
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private void setupTruststoreIfApplicable(HttpURLConnection connection) {
|
||||
if (connection instanceof HttpsURLConnection && sslFactory != null) {
|
||||
HttpsURLConnection con = (HttpsURLConnection) connection;
|
||||
con.setSSLSocketFactory(sslFactory);
|
||||
if (hostnameVerifier != null) {
|
||||
con.setHostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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.social;
|
||||
|
||||
import org.keycloak.broker.provider.IdentityProvider;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public interface SocialIdentityProvider<C extends IdentityProviderModel> extends IdentityProvider<C> {
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* 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.social;
|
||||
|
||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public interface SocialIdentityProviderFactory<I extends SocialIdentityProvider> extends IdentityProviderFactory<I> {
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.social;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author Pedro Igor
|
||||
*/
|
||||
public class SocialProviderSpi implements Spi {
|
||||
|
||||
public static final String SOCIAL_SPI_NAME = "social";
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return SOCIAL_SPI_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return SocialIdentityProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return SocialIdentityProviderFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClusterEvent extends Serializable {
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
/**
|
||||
* Task to be executed on all cluster nodes once it's notified.
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClusterListener {
|
||||
|
||||
/**
|
||||
* Registered task to be executed on all cluster nodes once it's notified from cache.
|
||||
*
|
||||
* @param event value of notification (Object added into the cache)
|
||||
*/
|
||||
void run(ClusterEvent event);
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Various utils related to clustering and concurrent tasks on cluster nodes
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClusterProvider extends Provider {
|
||||
|
||||
/**
|
||||
* Same value for all cluster nodes. It will use startup time of this server in non-cluster environment.
|
||||
*/
|
||||
int getClusterStartupTime();
|
||||
|
||||
|
||||
/**
|
||||
* Execute given task just if it's not already in progress (either on this or any other cluster node).
|
||||
*
|
||||
* @param taskKey
|
||||
* @param taskTimeoutInSeconds timeout for given task. If there is existing task in progress for longer time, it's considered outdated so we will start our task.
|
||||
* @param task
|
||||
* @param <T>
|
||||
* @return result with "executed" flag specifying if execution was executed or ignored.
|
||||
*/
|
||||
<T> ExecutionResult<T> executeIfNotExecuted(String taskKey, int taskTimeoutInSeconds, Callable<T> task);
|
||||
|
||||
|
||||
/**
|
||||
* Register task (listener) under given key. When this key will be put to the cache on any cluster node, the task will be executed
|
||||
*
|
||||
* @param taskKey
|
||||
* @param task
|
||||
*/
|
||||
void registerListener(String taskKey, ClusterListener task);
|
||||
|
||||
|
||||
/**
|
||||
* Notify registered listeners on all cluster nodes
|
||||
*
|
||||
* @param taskKey
|
||||
* @param event
|
||||
*/
|
||||
void notify(String taskKey, ClusterEvent event);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClusterProviderFactory extends ProviderFactory<ClusterProvider> {
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClusterSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "cluster";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return ClusterProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return ClusterProviderFactory.class;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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.cluster;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ExecutionResult<T> {
|
||||
|
||||
private final boolean executed;
|
||||
private final T result;
|
||||
|
||||
private ExecutionResult(boolean executed, T result) {
|
||||
this.executed = executed;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public static <T> ExecutionResult<T> executed(T result) {
|
||||
return new ExecutionResult<>(true, result);
|
||||
}
|
||||
|
||||
public static <T> ExecutionResult<T> notExecuted() {
|
||||
return new ExecutionResult<>(false, null);
|
||||
}
|
||||
|
||||
public boolean isExecuted() {
|
||||
return executed;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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.connections.httpclient;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface HttpClientFactory extends ProviderFactory<HttpClientProvider> {
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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.connections.httpclient;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface HttpClientProvider extends Provider {
|
||||
HttpClient getHttpClient();
|
||||
|
||||
/**
|
||||
* Helper method
|
||||
*
|
||||
* @param uri
|
||||
* @param text
|
||||
* @return http response status
|
||||
* @throws IOException
|
||||
*/
|
||||
public int postText(String uri, String text) throws IOException;
|
||||
|
||||
/**
|
||||
* Helper method
|
||||
*
|
||||
* @param uri
|
||||
* @return response stream, you must close this stream or leaks will happen
|
||||
* @throws IOException
|
||||
*/
|
||||
public InputStream get(String uri) throws IOException;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.connections.httpclient;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class HttpClientSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "connectionsHttpClient";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return HttpClientProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return HttpClientFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.email;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class EmailException extends Exception {
|
||||
|
||||
public EmailException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public EmailException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 399 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user