/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig 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 the following location: * * 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.jasig.cas; import java.util.Map; import org.jasig.cas.authentication.Authentication; import org.jasig.cas.authentication.AuthenticationException; import org.jasig.cas.authentication.MixedPrincipalException; import org.jasig.cas.authentication.UsernamePasswordCredential; import org.jasig.cas.authentication.principal.Service; import org.jasig.cas.services.UnauthorizedServiceException; import org.jasig.cas.ticket.ExpirationPolicy; import org.jasig.cas.ticket.TicketException; import org.jasig.cas.ticket.TicketGrantingTicketImpl; import org.jasig.cas.ticket.TicketState; import org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy; import org.jasig.cas.ticket.support.NeverExpiresExpirationPolicy; import org.jasig.cas.validation.Assertion; import org.jasig.cas.validation.Cas20WithoutProxyingValidationSpecification; import org.jasig.cas.validation.ValidationSpecification; import org.junit.Test; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; /** * @author Scott Battaglia * @since 3.0 */ public class CentralAuthenticationServiceImplTests extends AbstractCentralAuthenticationServiceTest { @Test(expected=AuthenticationException.class) public void testBadCredentialsOnTicketGrantingTicketCreation() throws Exception { getCentralAuthenticationService().createTicketGrantingTicket( TestUtils.getCredentialsWithDifferentUsernameAndPassword()); } @Test public void testGoodCredentialsOnTicketGrantingTicketCreation() throws Exception { try { assertNotNull(getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword())); } catch (final TicketException e) { fail(TestUtils.CONST_EXCEPTION_NON_EXPECTED); } } @Test public void testDestroyTicketGrantingTicketWithNonExistantTicket() { getCentralAuthenticationService().destroyTicketGrantingTicket("test"); } @Test public void testDestroyTicketGrantingTicketWithValidTicket() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); getCentralAuthenticationService().destroyTicketGrantingTicket(ticketId); } @Test(expected=ClassCastException.class) public void testDestroyTicketGrantingTicketWithInvalidTicket() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicketId = getCentralAuthenticationService() .grantServiceTicket(ticketId, TestUtils.getService()); getCentralAuthenticationService().destroyTicketGrantingTicket( serviceTicketId); } @Test public void testGrantServiceTicketWithValidTicketGrantingTicket() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); getCentralAuthenticationService().grantServiceTicket(ticketId, TestUtils.getService()); } @Test(expected=TicketException.class) public void testGrantServiceTicketWithInvalidTicketGrantingTicket() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); getCentralAuthenticationService().destroyTicketGrantingTicket(ticketId); getCentralAuthenticationService().grantServiceTicket(ticketId, TestUtils.getService()); } @Test(expected=TicketException.class) public void testGrantServiceTicketWithExpiredTicketGrantingTicket() throws Exception { ((CentralAuthenticationServiceImpl) getCentralAuthenticationService()).setTicketGrantingTicketExpirationPolicy( new ExpirationPolicy() { private static final long serialVersionUID = 1L; public boolean isExpired(final TicketState ticket) { return true; }}); final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); try { getCentralAuthenticationService().grantServiceTicket(ticketId, TestUtils.getService()); } finally { ((CentralAuthenticationServiceImpl) getCentralAuthenticationService()).setTicketGrantingTicketExpirationPolicy( new NeverExpiresExpirationPolicy()); } } @Test public void testDelegateTicketGrantingTicketWithProperParams() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicketId = getCentralAuthenticationService() .grantServiceTicket(ticketId, TestUtils.getService()); getCentralAuthenticationService().delegateTicketGrantingTicket( serviceTicketId, TestUtils.getHttpBasedServiceCredentials()); } @Test(expected=AuthenticationException.class) public void testDelegateTicketGrantingTicketWithBadCredentials() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicketId = getCentralAuthenticationService() .grantServiceTicket(ticketId, TestUtils.getService()); getCentralAuthenticationService().delegateTicketGrantingTicket( serviceTicketId, TestUtils.getBadHttpBasedServiceCredentials()); } @Test(expected=TicketException.class) public void testDelegateTicketGrantingTicketWithBadServiceTicket() throws Exception { final String ticketId = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicketId = getCentralAuthenticationService() .grantServiceTicket(ticketId, TestUtils.getService()); getCentralAuthenticationService().destroyTicketGrantingTicket(ticketId); getCentralAuthenticationService().delegateTicketGrantingTicket( serviceTicketId, TestUtils.getHttpBasedServiceCredentials()); } @Test public void testGrantServiceTicketWithValidCredentials() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); getCentralAuthenticationService().grantServiceTicket( ticketGrantingTicket, TestUtils.getService(), TestUtils.getCredentialsWithSameUsernameAndPassword()); } @Test(expected=AuthenticationException.class) public void testGrantServiceTicketWithInvalidCredentials() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); getCentralAuthenticationService().grantServiceTicket( ticketGrantingTicket, TestUtils.getService(), TestUtils.getBadHttpBasedServiceCredentials()); } @Test(expected=MixedPrincipalException.class) public void testGrantServiceTicketWithDifferentCredentials() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword("testA")); getCentralAuthenticationService().grantServiceTicket( ticketGrantingTicket, TestUtils.getService(), TestUtils.getCredentialsWithSameUsernameAndPassword("testB")); } @Test public void testValidateServiceTicketWithExpires() throws Exception { ((CentralAuthenticationServiceImpl) getCentralAuthenticationService()) .setServiceTicketExpirationPolicy(new MultiTimeUseOrTimeoutExpirationPolicy( 1, 1100)); final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicket = getCentralAuthenticationService() .grantServiceTicket(ticketGrantingTicket, TestUtils.getService()); getCentralAuthenticationService().validateServiceTicket(serviceTicket, TestUtils.getService()); assertFalse(getTicketRegistry().deleteTicket(serviceTicket)); ((CentralAuthenticationServiceImpl) getCentralAuthenticationService()) .setServiceTicketExpirationPolicy(new NeverExpiresExpirationPolicy()); } @Test public void testValidateServiceTicketWithValidService() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicket = getCentralAuthenticationService() .grantServiceTicket(ticketGrantingTicket, TestUtils.getService()); getCentralAuthenticationService().validateServiceTicket(serviceTicket, TestUtils.getService()); } @Test(expected=UnauthorizedServiceException.class) public void testValidateServiceTicketWithInvalidService() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicket = getCentralAuthenticationService() .grantServiceTicket(ticketGrantingTicket, TestUtils.getService()); getCentralAuthenticationService().validateServiceTicket( serviceTicket, TestUtils.getService("test2")); } @Test(expected=TicketException.class) public void testValidateServiceTicketWithInvalidServiceTicket() throws Exception { final String ticketGrantingTicket = getCentralAuthenticationService() .createTicketGrantingTicket( TestUtils.getCredentialsWithSameUsernameAndPassword()); final String serviceTicket = getCentralAuthenticationService() .grantServiceTicket(ticketGrantingTicket, TestUtils.getService()); getCentralAuthenticationService().destroyTicketGrantingTicket( ticketGrantingTicket); getCentralAuthenticationService().validateServiceTicket( serviceTicket, TestUtils.getService()); } @Test(expected=TicketException.class) public void testValidateServiceTicketNonExistantTicket() throws Exception { getCentralAuthenticationService().validateServiceTicket("test", TestUtils.getService()); } @Test public void testValidateServiceTicketWithoutUsernameAttribute() throws Exception { UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, TestUtils.getService()); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, TestUtils.getService()); final Authentication auth = assertion.getPrimaryAuthentication(); assertEquals(auth.getPrincipal().getId(), cred.getUsername()); } @Test public void testValidateServiceTicketWithDefaultUsernameAttribute() throws Exception { UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); Service svc = TestUtils.getService("testDefault"); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, svc); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, svc); final Authentication auth = assertion.getPrimaryAuthentication(); assertEquals(auth.getPrincipal().getId(), cred.getUsername()); } @Test public void testValidateServiceTicketWithUsernameAttribute() throws Exception { UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); Service svc = TestUtils.getService("eduPersonTest"); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, svc); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, svc); assertEquals("developer", assertion.getPrimaryAuthentication().getPrincipal().getId()); } @Test public void testValidateServiceTicketNoAttributesReturned() throws Exception { final Service service = TestUtils.getService(); final UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, service); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, service); final Authentication auth = assertion.getPrimaryAuthentication(); assertEquals(0, auth.getPrincipal().getAttributes().size()); } @Test public void testValidateServiceTicketReturnAllAttributes() throws Exception { final Service service = TestUtils.getService("eduPersonTest"); final UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, service); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, service); final Authentication auth = assertion.getPrimaryAuthentication(); assertEquals(3, auth.getPrincipal().getAttributes().size()); } @Test public void testValidateServiceTicketReturnOnlyAllowedAttribute() throws Exception { final Service service = TestUtils.getService("eduPersonTestInvalid"); final UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, service); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, service); final Authentication auth = assertion.getPrimaryAuthentication(); Map<String, Object> attributes = auth.getPrincipal().getAttributes(); assertEquals(1, attributes.size()); assertEquals("adopters", attributes.get("groupMembership")); } @Test public void testValidateServiceTicketAnonymous() throws Exception { final Service service = TestUtils.getService("testAnonymous"); final UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, service); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, service); final Authentication auth = assertion.getPrimaryAuthentication(); assertNotEquals(cred.getUsername(), auth.getPrincipal().getId()); } @Test public void testValidateServiceTicketWithInvalidUsernameAttribute() throws Exception { final UsernamePasswordCredential cred = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(cred); final Service svc = TestUtils.getService("eduPersonTestInvalid"); final String serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket, svc); final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket, svc); final Authentication auth = assertion.getPrimaryAuthentication(); /* * The attribute specified for this service does not resolve. * Therefore, we expect the default to be returned. */ assertEquals(auth.getPrincipal().getId(), cred.getUsername()); } /** * This test simulates : * - a first authentication for a default service * - a second authentication with the renew parameter and the same service (and same credentials) * - a validation of the second ticket. * * When supplemental authentications were returned with the chained authentications, the validation specification * failed as it only expects one authentication. Thus supplemental authentications should not be returned in the * chained authentications. Both concepts are orthogonal. * * @throws TicketException * @throws AuthenticationException */ @Test public void authenticateTwiceWithRenew() throws TicketException, AuthenticationException { final CentralAuthenticationService cas = getCentralAuthenticationService(); final Service svc = TestUtils.getService("testDefault"); final UsernamePasswordCredential goodCredential = TestUtils.getCredentialsWithSameUsernameAndPassword(); final String tgtId = cas.createTicketGrantingTicket(goodCredential); cas.grantServiceTicket(tgtId, svc); // simulate renew with new good same credentials final String st2Id = cas.grantServiceTicket(tgtId, svc, goodCredential); final Assertion assertion = cas.validateServiceTicket(st2Id, svc); final ValidationSpecification validationSpecification = new Cas20WithoutProxyingValidationSpecification(); assertTrue(validationSpecification.isSatisfiedBy(assertion)); } /** * This test checks that the TGT destruction happens properly for a remote registry. * It previously failed when the deletion happens before the ticket was marked expired because an update was necessary for that. * * @throws AuthenticationException * @throws TicketException */ @Test public void testDestroyRemoteRegistry() throws TicketException, AuthenticationException { final MockOnlyOneTicketRegistry registry = new MockOnlyOneTicketRegistry(); final TicketGrantingTicketImpl tgt = new TicketGrantingTicketImpl("TGT-1", mock(Authentication.class), mock(ExpirationPolicy.class)); final MockExpireUpdateTicketLogoutManager logoutManager = new MockExpireUpdateTicketLogoutManager(registry); // consider authentication has happened and the TGT is in the registry registry.addTicket(tgt); // create a new CASimpl final CentralAuthenticationServiceImpl cas = new CentralAuthenticationServiceImpl(registry, null, null, null, null, null, null, null, logoutManager); // destroy to mark expired and then delete : the opposite would fail with a "No ticket to update" error from the registry cas.destroyTicketGrantingTicket(tgt.getId()); } }