/* * Copyright 2002-2009 the original author or authors. * * 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.springframework.flex.security3; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.security.Principal; import java.util.ArrayList; import java.util.List; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.flex.core.AbstractMessageBrokerTests; import org.springframework.flex.core.LoginCommandConfigProcessor; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import flex.messaging.FlexContext; import flex.messaging.security.LoginManager; public class SpringSecurityLoginCommandTests extends AbstractMessageBrokerTests { @Mock private AuthenticationManager mgr; @Mock private SessionAuthenticationStrategy sas; @Mock private RememberMeServices rms; private MockHttpServletRequest request; private MockHttpServletResponse response; private SpringSecurityLoginCommand cmd; @Before public void setUp() throws Exception { this.request = new MockHttpServletRequest(); this.response = new MockHttpServletResponse(); FlexContext.setThreadLocalHttpRequest(this.request); FlexContext.setThreadLocalHttpResponse(this.response); MockitoAnnotations.initMocks(this); List<LogoutHandler> logoutHandlers = new ArrayList<LogoutHandler>(); logoutHandlers.add(new SecurityContextLogoutHandler()); this.cmd = new SpringSecurityLoginCommand(mgr); this.cmd.setLogoutHandlers(logoutHandlers); this.cmd.setSessionAuthenticationStrategy(sas); this.cmd.setRememberMeServices(rms); this.cmd.afterPropertiesSet(); } @After public void tearDown() throws Exception { FlexContext.clearThreadLocalObjects(); } @Test public void failure() throws Exception { String username = "foo"; String password = "bar"; when(mgr.authenticate(isA(Authentication.class))).thenThrow(new UsernameNotFoundException("Authentication failed")); try { this.cmd.doAuthentication(username, password); fail("An AuthenticationException was not thrown"); } catch (AuthenticationException ex) { // expected } verify(rms).loginFail(request, response); } @Test public void validLogin() throws Exception { String username = "foo"; String password = "bar"; Authentication auth = new UsernamePasswordAuthenticationToken(username, password); when(mgr.authenticate(isA(Authentication.class))).thenReturn(auth); Principal principal = this.cmd.doAuthentication(username, password); assertNotNull("A non-null Principal was not returned", principal); assertEquals(username, principal.getName()); verify(sas).onAuthentication(auth, this.request, this.response); verify(rms).loginSuccess(request, response, auth); } @Test public void matchingAuthority() throws Exception { List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); authorities.add(new GrantedAuthorityImpl("ROLE_USER")); authorities.add(new GrantedAuthorityImpl("ROLE_ABUSER")); Principal principal = new UsernamePasswordAuthenticationToken("foo", "bar", authorities); List<String> roles = new ArrayList<String>(); roles.add("ROLE_ADMIN"); roles.add("ROLE_USER"); assertTrue("Authorization should pass", this.cmd.doAuthorization(principal, roles)); } @Test public void noMatchingAuthority() throws Exception { List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); authorities.add(new GrantedAuthorityImpl("ROLE_USER")); authorities.add(new GrantedAuthorityImpl("ROLE_ABUSER")); Principal principal = new UsernamePasswordAuthenticationToken("foo", "bar", authorities); List<String> roles = new ArrayList<String>(); roles.add("ROLE_ADMIN"); assertFalse("Authorization should not pass", this.cmd.doAuthorization(principal, roles)); } @Test public void loginCommandRegisteredWithDefaultConfig() throws Exception { setDirty(); addStartupProcessor(new LoginCommandConfigProcessor(this.cmd)); LoginManager mgr = getMessageBroker().getLoginManager(); assertTrue("LoginManager not started", mgr.isStarted()); assertSame("SpringSecurityLoginCommand not set on the LoginManager", this.cmd, mgr.getLoginCommand()); assertFalse("Should default to per session authentication", mgr.isPerClientAuthentication()); } @Test public void loginCommandRegisteredWithPerClientConfig() throws Exception { setDirty(); this.cmd.setPerClientAuthentication(true); LoginCommandConfigProcessor processor = new LoginCommandConfigProcessor(this.cmd); processor.setPerClientAuthentication(true); addStartupProcessor(processor); LoginManager mgr = getMessageBroker().getLoginManager(); assertTrue("LoginManager not started", mgr.isStarted()); assertSame("SpringSecurityLoginCommand not set on the LoginManager", this.cmd, mgr.getLoginCommand()); assertTrue("Should be set to per client authentication", mgr.isPerClientAuthentication()); } @Test public void logoutWithDefaults() throws Exception { String username = "foo"; String password = "bar"; Principal principal = this.cmd.doAuthentication(username, password); MockHttpSession originalSession = (MockHttpSession) this.request.getSession(); SecurityContext original = SecurityContextHolder.getContext(); this.cmd.logout(principal); assertTrue("SecurityContext was not cleared", original != SecurityContextHolder.getContext()); assertNull(this.request.getSession(false)); assertTrue(originalSession.isInvalid()); } @Test public void logoutWithPerClientAuthentication() throws Exception { List<LogoutHandler> logoutHandlers = new ArrayList<LogoutHandler>(); SecurityContextLogoutHandler handler = new SecurityContextLogoutHandler(); handler.setInvalidateHttpSession(false); logoutHandlers.add(handler); this.cmd.setPerClientAuthentication(true); this.cmd.setLogoutHandlers(logoutHandlers); String username = "foo"; String password = "bar"; Principal principal = this.cmd.doAuthentication(username, password); MockHttpSession originalSession = (MockHttpSession) this.request.getSession(); SecurityContext original = SecurityContextHolder.getContext(); this.cmd.logout(principal); assertTrue("SecurityContext was not cleared", original != SecurityContextHolder.getContext()); assertNotNull(this.request.getSession(false)); assertTrue(!originalSession.isInvalid()); } }