mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 06:01:22 +00:00
GUACAMOLE-204: Implementation of CAS SSO module for Guacamole authentication.
This commit is contained in:
committed by
Nick Couchman
parent
1c197ae467
commit
b278970076
53
extensions/guacamole-auth-cas/src/main/assembly/dist.xml
Normal file
53
extensions/guacamole-auth-cas/src/main/assembly/dist.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you 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.
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
|
||||
<id>dist</id>
|
||||
<baseDirectory>${project.artifactId}-${project.version}</baseDirectory>
|
||||
|
||||
<!-- Output tar.gz -->
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
|
||||
<!-- Include licenses and extension .jar -->
|
||||
<fileSets>
|
||||
|
||||
<!-- Include licenses -->
|
||||
<fileSet>
|
||||
<outputDirectory></outputDirectory>
|
||||
<directory>src/licenses</directory>
|
||||
</fileSet>
|
||||
|
||||
<!-- Include extension .jar -->
|
||||
<fileSet>
|
||||
<directory>target</directory>
|
||||
<outputDirectory></outputDirectory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
|
||||
</fileSets>
|
||||
|
||||
</assembly>
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.form.Field;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
||||
import org.apache.guacamole.auth.cas.conf.ConfigurationService;
|
||||
import org.apache.guacamole.auth.cas.form.CASTicketField;
|
||||
import org.apache.guacamole.auth.cas.ticket.TicketValidationService;
|
||||
import org.apache.guacamole.auth.cas.user.AuthenticatedUser;
|
||||
|
||||
/**
|
||||
* Service providing convenience functions for the CAS AuthenticationProvider
|
||||
* implementation.
|
||||
*
|
||||
* @author Nick Couchman
|
||||
*/
|
||||
public class AuthenticationProviderService {
|
||||
|
||||
/**
|
||||
* Service for retrieving CAS configuration information.
|
||||
*/
|
||||
@Inject
|
||||
private ConfigurationService confService;
|
||||
|
||||
/**
|
||||
* Service for validating received ID tickets.
|
||||
*/
|
||||
@Inject
|
||||
private TicketValidationService ticketService;
|
||||
|
||||
/**
|
||||
* Provider for AuthenticatedUser objects.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<AuthenticatedUser> authenticatedUserProvider;
|
||||
|
||||
/**
|
||||
* Returns an AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials to use for authentication.
|
||||
*
|
||||
* @return
|
||||
* An AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while authenticating the user, or if access is
|
||||
* denied.
|
||||
*/
|
||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
String ticket = null;
|
||||
|
||||
// Pull CAS ticket from request if present
|
||||
HttpServletRequest request = credentials.getRequest();
|
||||
if (request != null) {
|
||||
ticket = request.getParameter(CASTicketField.PARAMETER_NAME);
|
||||
if (ticket != null) {
|
||||
AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
|
||||
authenticatedUser.init(ticketService.processUsername(ticket), credentials);
|
||||
return authenticatedUser;
|
||||
}
|
||||
}
|
||||
|
||||
// Request CAS ticket
|
||||
throw new GuacamoleInvalidCredentialsException("Invalid login.",
|
||||
new CredentialsInfo(Arrays.asList(new Field[] {
|
||||
|
||||
// CAS-specific ticket (will automatically redirect the user
|
||||
// to the authorization page via JavaScript)
|
||||
new CASTicketField(
|
||||
confService.getAuthorizationEndpoint(),
|
||||
confService.getRedirectURI()
|
||||
)
|
||||
|
||||
}))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* Guacamole authentication backend which authenticates users using an
|
||||
* arbitrary external system implementing CAS. No storage for connections is
|
||||
* provided - only authentication. Storage must be provided by some other
|
||||
* extension.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class CASAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Injector which will manage the object graph of this authentication
|
||||
* provider.
|
||||
*/
|
||||
private final Injector injector;
|
||||
|
||||
/**
|
||||
* Creates a new CASAuthenticationProvider that authenticates users
|
||||
* against an CAS service
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If a required property is missing, or an error occurs while parsing
|
||||
* a property.
|
||||
*/
|
||||
public CASAuthenticationProvider() throws GuacamoleException {
|
||||
|
||||
// Set up Guice injector.
|
||||
injector = Guice.createInjector(
|
||||
new CASAuthenticationProviderModule(this)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "cas";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Attempt to authenticate user with given credentials
|
||||
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||
return authProviderService.authenticateUser(credentials);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedUser updateAuthenticatedUser(
|
||||
AuthenticatedUser authenticatedUser, Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// No update necessary
|
||||
return authenticatedUser;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||
throws GuacamoleException {
|
||||
|
||||
// No associated data whatsoever
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext updateUserContext(UserContext context,
|
||||
AuthenticatedUser authenticatedUser, Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// No update necessary
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas;
|
||||
|
||||
import org.apache.guacamole.auth.cas.conf.ConfigurationService;
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.environment.Environment;
|
||||
import org.apache.guacamole.environment.LocalEnvironment;
|
||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.apache.guacamole.auth.cas.ticket.TicketValidationService;
|
||||
|
||||
/**
|
||||
* Guice module which configures CAS-specific injections.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class CASAuthenticationProviderModule extends AbstractModule {
|
||||
|
||||
/**
|
||||
* Guacamole server environment.
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* A reference to the CASAuthenticationProvider on behalf of which this
|
||||
* module has configured injection.
|
||||
*/
|
||||
private final AuthenticationProvider authProvider;
|
||||
|
||||
/**
|
||||
* Creates a new CAS authentication provider module which configures
|
||||
* injection for the CASAuthenticationProvider.
|
||||
*
|
||||
* @param authProvider
|
||||
* The AuthenticationProvider for which injection is being configured.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the Guacamole server
|
||||
* environment.
|
||||
*/
|
||||
public CASAuthenticationProviderModule(AuthenticationProvider authProvider)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get local environment
|
||||
this.environment = new LocalEnvironment();
|
||||
|
||||
// Store associated auth provider
|
||||
this.authProvider = authProvider;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
// Bind core implementations of guacamole-ext classes
|
||||
bind(AuthenticationProvider.class).toInstance(authProvider);
|
||||
bind(Environment.class).toInstance(environment);
|
||||
|
||||
// Bind CAS-specific services
|
||||
bind(ConfigurationService.class);
|
||||
bind(TicketValidationService.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas.conf;
|
||||
|
||||
import org.apache.guacamole.properties.StringGuacamoleProperty;
|
||||
|
||||
/**
|
||||
* Provides properties required for use of the CAS authentication provider.
|
||||
* These properties will be read from guacamole.properties when the CAS
|
||||
* authentication provider is used.
|
||||
*
|
||||
* @author Nick Couchman
|
||||
*/
|
||||
public class CASGuacamoleProperties {
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private CASGuacamoleProperties() {}
|
||||
|
||||
/**
|
||||
* The authorization endpoint (URI) of the CAS service.
|
||||
*/
|
||||
public static final StringGuacamoleProperty CAS_AUTHORIZATION_ENDPOINT =
|
||||
new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "cas-authorization-endpoint"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The URI that the CAS service should redirect to after the
|
||||
* authentication process is complete. This must be the full URL that a
|
||||
* user would enter into their browser to access Guacamole.
|
||||
*/
|
||||
public static final StringGuacamoleProperty CAS_REDIRECT_URI =
|
||||
new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "cas-redirect-uri"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas.conf;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.environment.Environment;
|
||||
|
||||
/**
|
||||
* Service for retrieving configuration information regarding the CAS service.
|
||||
*
|
||||
* @author Nick Couchman
|
||||
*/
|
||||
public class ConfigurationService {
|
||||
|
||||
/**
|
||||
* The Guacamole server environment.
|
||||
*/
|
||||
@Inject
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Returns the authorization endpoint (URI) of the CAS service as
|
||||
* configured with guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* The authorization endpoint of the CAS service, as configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed, or if the authorization
|
||||
* endpoint property is missing.
|
||||
*/
|
||||
public String getAuthorizationEndpoint() throws GuacamoleException {
|
||||
return environment.getRequiredProperty(CASGuacamoleProperties.CAS_AUTHORIZATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI that the CAS service should redirect to after
|
||||
* the authentication process is complete, as configured with
|
||||
* guacamole.properties. This must be the full URL that a user would enter
|
||||
* into their browser to access Guacamole.
|
||||
*
|
||||
* @return
|
||||
* The client secret to use when communicating with the CAS service,
|
||||
* as configured with guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed, or if the redirect URI
|
||||
* property is missing.
|
||||
*/
|
||||
public String getRedirectURI() throws GuacamoleException {
|
||||
return environment.getRequiredProperty(CASGuacamoleProperties.CAS_REDIRECT_URI);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas.form;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SecureRandom;
|
||||
import org.apache.guacamole.form.Field;
|
||||
|
||||
|
||||
/**
|
||||
* Field definition which represents the ticket returned by an CAS service.
|
||||
* Within the user interface, this will be rendered as an appropriate "Log in
|
||||
* with ..." button which links to the CAS service.
|
||||
*
|
||||
* @author Nick Couchman
|
||||
*/
|
||||
public class CASTicketField extends Field {
|
||||
|
||||
/**
|
||||
* The standard HTTP parameter which will be included within the URL by all
|
||||
* CAS services upon successful authentication and redirect.
|
||||
*/
|
||||
public static final String PARAMETER_NAME = "ticket";
|
||||
|
||||
/**
|
||||
* The full URI which the field should link to.
|
||||
*/
|
||||
private final String authorizationURI;
|
||||
|
||||
/**
|
||||
* Creates a new CAS "ticket" field which links to the given CAS
|
||||
* service using the provided client ID. Successful authentication at the
|
||||
* CAS service will result in the client being redirected to the specified
|
||||
* redirect URI. The CAS ticket will be embedded in the fragment (the part
|
||||
* following the hash symbol) of that URI, which the JavaScript side of
|
||||
* this extension will move to the query parameters.
|
||||
*
|
||||
* @param authorizationEndpoint
|
||||
* The full URL of the endpoint accepting CAS authentication
|
||||
* requests.
|
||||
*
|
||||
* @param clientID
|
||||
* The ID of the CAS client. This is normally determined ahead of
|
||||
* time by the CAS service through some manual credential request
|
||||
* procedure.
|
||||
*
|
||||
* @param redirectURI
|
||||
* The URI that the CAS service should redirect to upon successful
|
||||
* authentication.
|
||||
*/
|
||||
public CASTicketField(String authorizationEndpoint, String redirectURI) {
|
||||
|
||||
// Init base field properties
|
||||
super(PARAMETER_NAME, "GUAC_CAS_TICKET");
|
||||
|
||||
// Build authorization URI from given values
|
||||
try {
|
||||
this.authorizationURI = authorizationEndpoint
|
||||
+ "?service=" + URLEncoder.encode(redirectURI, "UTF-8");
|
||||
}
|
||||
|
||||
// Java is required to provide UTF-8 support
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full URI that this field should link to when a new ticket
|
||||
* needs to be obtained from the CAS service.
|
||||
*
|
||||
* @return
|
||||
* The full URI that this field should link to.
|
||||
*/
|
||||
public String getAuthorizationURI() {
|
||||
return authorizationURI;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas.ticket;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleSecurityException;
|
||||
import org.apache.guacamole.GuacamoleServerException;
|
||||
import org.apache.guacamole.auth.cas.conf.ConfigurationService;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipal;
|
||||
import org.jasig.cas.client.validation.Assertion;
|
||||
import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
|
||||
import org.jasig.cas.client.validation.TicketValidationException;
|
||||
|
||||
/**
|
||||
* Service for validating ID tickets forwarded to us by the client, verifying
|
||||
* that they did indeed come from the CAS service.
|
||||
*
|
||||
* @author Nick Couchman
|
||||
*/
|
||||
public class TicketValidationService {
|
||||
|
||||
/**
|
||||
* Service for retrieving CAS configuration information.
|
||||
*/
|
||||
@Inject
|
||||
private ConfigurationService confService;
|
||||
|
||||
/**
|
||||
* Validates and parses the given ID ticket, returning the username contained
|
||||
* therein, as defined by the username claim type given in
|
||||
* guacamole.properties. If the username claim type is missing or the ID
|
||||
* ticket is invalid, an exception is thrown instead.
|
||||
*
|
||||
* @param ticket
|
||||
* The ID ticket to validate and parse.
|
||||
*
|
||||
* @return
|
||||
* The username contained within the given ID ticket.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the ID ticket is not valid, the username claim type is missing, or
|
||||
* guacamole.properties could not be parsed.
|
||||
*/
|
||||
public String processUsername(String ticket) throws GuacamoleException {
|
||||
AttributePrincipal principal = null;
|
||||
|
||||
// Retrieve the configured CAS URL and establish a ticket validator
|
||||
String casServerUrl = confService.getAuthorizationEndpoint();
|
||||
Cas20ProxyTicketValidator sv = new Cas20ProxyTicketValidator(casServerUrl);
|
||||
sv.setAcceptAnyProxy(true);
|
||||
try {
|
||||
String confRedirectURI = confService.getRedirectURI();
|
||||
Assertion a = sv.validate(ticket, confRedirectURI);
|
||||
principal = a.getPrincipal();
|
||||
}
|
||||
catch (TicketValidationException e)
|
||||
Throw new GuacamoleException("Ticket validation failed.", e);
|
||||
|
||||
return principal.getName();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.guacamole.auth.cas.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
|
||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
|
||||
/**
|
||||
* An CAS-specific implementation of AuthenticatedUser, associating a
|
||||
* username and particular set of credentials with the CAS authentication
|
||||
* provider.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class AuthenticatedUser extends AbstractAuthenticatedUser {
|
||||
|
||||
/**
|
||||
* Reference to the authentication provider associated with this
|
||||
* authenticated user.
|
||||
*/
|
||||
@Inject
|
||||
private AuthenticationProvider authProvider;
|
||||
|
||||
/**
|
||||
* The credentials provided when this user was authenticated.
|
||||
*/
|
||||
private Credentials credentials;
|
||||
|
||||
/**
|
||||
* Initializes this AuthenticatedUser using the given username and
|
||||
* credentials.
|
||||
*
|
||||
* @param username
|
||||
* The username of the user that was authenticated.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials provided when this user was authenticated.
|
||||
*/
|
||||
public void init(String username, Credentials credentials) {
|
||||
this.credentials = credentials;
|
||||
setIdentifier(username.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationProvider getAuthenticationProvider() {
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credentials getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
}
|
23
extensions/guacamole-auth-cas/src/main/resources/cas.css
Normal file
23
extensions/guacamole-auth-cas/src/main/resources/cas.css
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
|
||||
/* Hide login dialog */
|
||||
.login-ui div.login-dialog {
|
||||
display: none;
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Config block which registers CAS-specific field types.
|
||||
*/
|
||||
angular.module('guacCAS').config(['formServiceProvider',
|
||||
function guacCASConfig(formServiceProvider) {
|
||||
|
||||
// Define field for ticket from CAS service
|
||||
formServiceProvider.registerFieldType("GUAC_CAS_TICKET", {
|
||||
templateUrl : '',
|
||||
controller : 'guacCASController',
|
||||
module : 'guacCAS'
|
||||
});
|
||||
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Config block which augments the existing routing, providing special handling
|
||||
* for the "ticket=" fragments provided by OpenID Connect.
|
||||
*/
|
||||
angular.module('index').config(['$routeProvider',
|
||||
function indexRouteConfig($routeProvider) {
|
||||
|
||||
var curPath = window.location.href;
|
||||
var ticketPos = curPath.indexOf("?ticket=") + 8;
|
||||
var hashPos = curPath.indexOf("#/");
|
||||
if(ticketPos > 0 && ticketPos < hashPos) {
|
||||
var ticket = curPath.substring(ticketPos, hashPos);
|
||||
var newPath = curPath.substring(0,ticketPos - 8) + '#/?ticket=' + ticket;
|
||||
window.location=newPath;
|
||||
}
|
||||
|
||||
}]);
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controller for the "GUAC_CAS_TICKET" field which simply redirects the user
|
||||
* immediately to the authorization URI.
|
||||
*/
|
||||
angular.module('guacCAS').controller('guacCASController', ['$scope',
|
||||
function guacCASController($scope) {
|
||||
|
||||
// Redirect to authorization URI
|
||||
window.location = $scope.field.authorizationURI;
|
||||
|
||||
}]);
|
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module which provides handling for CAS authentication.
|
||||
*/
|
||||
angular.module('guacCAS', [
|
||||
'form',
|
||||
'ngRoute',
|
||||
]);
|
||||
|
||||
// Ensure the CAS module is loaded along with the rest of the app
|
||||
angular.module('index').requires.push('guacCAS');
|
@@ -0,0 +1,22 @@
|
||||
{
|
||||
|
||||
"guacamoleVersion" : "0.9.11-incubating",
|
||||
|
||||
"name" : "CAS Authentication Extension",
|
||||
"namespace" : "guac-cas",
|
||||
|
||||
"authProviders" : [
|
||||
"org.apache.guacamole.auth.cas.CASAuthenticationProvider"
|
||||
],
|
||||
|
||||
"js" : [
|
||||
"casModule.js",
|
||||
"casController.js",
|
||||
"casConfig.js"
|
||||
],
|
||||
|
||||
"css" : [
|
||||
"cas.css"
|
||||
]
|
||||
|
||||
}
|
Reference in New Issue
Block a user