Skip to content
This repository was archived by the owner on Dec 12, 2018. It is now read-only.

Commit f28c07c

Browse files
author
Mario
committed
1158 - Added ITs for SpringSecurity Loging and Logout Handlers + Added PUT to de list of allowed CORS methods
1 parent db60d43 commit f28c07c

File tree

11 files changed

+281
-11
lines changed

11 files changed

+281
-11
lines changed

extensions/servlet/src/main/resources/com/stormpath/sdk/servlet/config/web.stormpath.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,4 @@ stormpath.web.cors.enabled = true
355355
#Comma separated list of allowed origins
356356
stormpath.web.cors.allowed.originUris =
357357
stormpath.web.cors.allowed.headers = Content-Type,Accept,X-Requested-With,remember-me
358-
stormpath.web.cors.allowed.methods = POST,GET,OPTIONS,DELETE
358+
stormpath.web.cors.allowed.methods = POST,GET,OPTIONS,DELETE,PUT

extensions/spring/boot/stormpath-webmvc-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@
10241024
"name": "stormpath.web.cors.allowed.methods",
10251025
"type": "java.lang.String",
10261026
"description": "Comma separated list of allowed methods for a CORS request.",
1027-
"defaultValue": "POST,GET,OPTIONS,DELETE"
1027+
"defaultValue": "POST,GET,OPTIONS,DELETE,PUT"
10281028
}
10291029
]
10301030
}

extensions/spring/stormpath-spring-security-webmvc/src/main/java/com/stormpath/spring/config/AbstractStormpathWebSecurityConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public abstract class AbstractStormpathWebSecurityConfiguration {
131131
@Value("#{ @environment['stormpath.web.cors.allowed.headers'] ?: 'Content-Type,Accept,X-Requested-With,remember-me' }")
132132
protected String corsAllowedHeaders;
133133

134-
@Value("#{ @environment['stormpath.web.cors.allowed.methods'] ?: 'POST,GET,OPTIONS,DELETE' }")
134+
@Value("#{ @environment['stormpath.web.cors.allowed.methods'] ?: 'POST,GET,OPTIONS,DELETE,PUT' }")
135135
protected String corsAllowedMethods;
136136

137137
@Value("#{ @environment['stormpath.web.stormpathFilter.enabled'] ?: true }")

extensions/spring/stormpath-spring-security-webmvc/src/main/java/com/stormpath/spring/config/StormpathWebSecurityConfigurer.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import com.stormpath.sdk.servlet.mvc.WebHandler;
2727
import com.stormpath.spring.filter.ContentNegotiationSpringSecurityAuthenticationFilter;
2828
import com.stormpath.spring.filter.StormpathSecurityContextPersistenceFilter;
29-
//import com.stormpath.spring.oauth.OAuthAuthenticationSpringSecurityProcessingFilter;
30-
//import com.stormpath.spring.filter.StormpathWrapperFilter;
3129
import com.stormpath.spring.filter.StormpathWrapperFilter;
3230
import com.stormpath.spring.security.provider.SocialCallbackSpringSecurityProcessingFilter;
3331
import org.slf4j.Logger;

extensions/spring/stormpath-spring-security-webmvc/src/test/groovy/com/stormpath/spring/config/CorsFilterIT.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class CorsFilterIT extends AbstractTestNGSpringContextTests {
106106
void testAccessControlRequestMethodRequestFailsForPUT() {
107107
mvc.perform(options(new URI("/me"))
108108
.header("Origin", "http://localhost:3000")
109-
.header("Access-Control-Request-Method", "PUT") //PUT is not allowed
109+
.header("Access-Control-Request-Method", "HEAD") //HEAD is not allowed
110110
.accept(MediaType.APPLICATION_JSON))
111111
.andExpect(status().is(HttpServletResponse.SC_FORBIDDEN)); //403
112112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright 2016 Stormpath, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.stormpath.spring.config
17+
18+
import org.springframework.context.annotation.Bean
19+
import org.springframework.context.annotation.Configuration
20+
import org.springframework.context.annotation.PropertySource
21+
import org.springframework.security.config.annotation.web.builders.HttpSecurity
22+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
23+
import org.springframework.security.core.Authentication
24+
import org.springframework.security.core.AuthenticationException
25+
import org.springframework.security.web.authentication.AuthenticationFailureHandler
26+
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
27+
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
28+
import org.springframework.security.web.authentication.logout.LogoutHandler
29+
30+
import javax.servlet.ServletException
31+
import javax.servlet.http.HttpServletRequest
32+
import javax.servlet.http.HttpServletResponse
33+
34+
import static com.stormpath.spring.config.StormpathWebSecurityConfigurer.stormpath
35+
36+
37+
/**
38+
* @since 1.3.0
39+
*/
40+
@Configuration
41+
@EnableStormpathWebSecurity
42+
@PropertySource("classpath:com/stormpath/spring/config/loginAndLogoutHandlers.properties")
43+
class LoginAndLogoutHandlersConfig extends WebSecurityConfigurerAdapter {
44+
45+
@Override
46+
protected void configure(HttpSecurity http) throws Exception {
47+
http.apply(stormpath());
48+
}
49+
50+
@Bean
51+
public AuthenticationSuccessHandler stormpathAuthenticationSuccessHandler() {
52+
return new CustomLoginSuccessHandler();
53+
}
54+
55+
@Bean
56+
public AuthenticationFailureHandler stormpathAuthenticationFailureHandler() {
57+
return new CustomLoginFailureHandler();
58+
}
59+
60+
@Bean
61+
public LogoutHandler stormpathLogoutHandler() {
62+
return new CustomLogoutHandler();
63+
}
64+
65+
class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
66+
67+
public boolean invoked = false
68+
69+
@Override
70+
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, final Authentication authentication) throws IOException, ServletException {
71+
invoked = true
72+
}
73+
}
74+
75+
class CustomLoginFailureHandler implements AuthenticationFailureHandler {
76+
77+
public boolean invoked = false
78+
79+
@Override
80+
void onAuthenticationFailure(HttpServletRequest request,
81+
HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
82+
invoked = true
83+
}
84+
}
85+
86+
class CustomLogoutHandler implements LogoutHandler {
87+
88+
public boolean invoked = false
89+
90+
@Override
91+
void logout(HttpServletRequest request, HttpServletResponse response,
92+
Authentication authentication) {
93+
invoked = true
94+
}
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2016 Stormpath, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.stormpath.spring.config
17+
18+
import org.springframework.beans.factory.annotation.Autowired
19+
import org.springframework.beans.factory.annotation.Qualifier
20+
import org.springframework.security.web.FilterChainProxy
21+
import org.springframework.security.web.authentication.AuthenticationFailureHandler
22+
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
23+
import org.springframework.security.web.authentication.logout.LogoutHandler
24+
import org.springframework.test.context.ContextConfiguration
25+
import org.springframework.test.context.web.WebAppConfiguration
26+
import org.springframework.test.web.servlet.MockMvc
27+
import org.springframework.test.web.servlet.setup.MockMvcBuilders
28+
import org.springframework.web.context.WebApplicationContext
29+
import org.testng.annotations.BeforeMethod
30+
import org.testng.annotations.Test
31+
32+
import javax.servlet.Filter
33+
34+
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated
35+
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated
36+
37+
import static org.testng.Assert.assertFalse
38+
import static org.testng.Assert.assertTrue
39+
40+
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
41+
42+
/**
43+
* Validates that https://github.com/stormpath/stormpath-sdk-java/issues/1158 is fixed
44+
*
45+
* @since 1.3.0
46+
*/
47+
@WebAppConfiguration
48+
@ContextConfiguration(classes = [LoginAndLogoutHandlersConfig.class, TwoAppTenantStormpathTestConfiguration.class])
49+
class LoginAndLogoutHandlersIT extends AbstractClientIT {
50+
51+
@Autowired
52+
WebApplicationContext context;
53+
54+
@Autowired
55+
@Qualifier("stormpathAuthenticationSuccessHandler")
56+
public AuthenticationSuccessHandler customLoginSuccessHandler;
57+
58+
@Autowired
59+
@Qualifier("stormpathAuthenticationFailureHandler")
60+
public AuthenticationFailureHandler customLoginFailureHandler;
61+
62+
@Autowired
63+
@Qualifier("stormpathLogoutHandler")
64+
public LogoutHandler customLogoutHandler;
65+
66+
@Autowired
67+
protected FilterChainProxy springSecurityFilterChain;
68+
69+
@Autowired
70+
protected Filter stormpathFilter;
71+
72+
private MockMvc mvc;
73+
74+
@BeforeMethod
75+
public void setup() {
76+
mvc = MockMvcBuilders.webAppContextSetup(context)
77+
.apply(StormpathMockMvcConfigurers.stormpath())
78+
.build()
79+
}
80+
81+
@Test
82+
void testHandlersAreInvoked() {
83+
84+
assertFalse customLoginSuccessHandler.invoked
85+
assertFalse customLoginFailureHandler.invoked
86+
assertFalse customLogoutHandler.invoked
87+
88+
def password = "P@\$sw0rd*"
89+
def account = createTempAccount(password)
90+
91+
mvc.perform(SecurityMockMvcLoginRequestBuilder.formLogin().login(account.getEmail()).password("this_password_will_fail")).andExpect(unauthenticated())
92+
93+
assertFalse customLoginSuccessHandler.invoked
94+
assertTrue customLoginFailureHandler.invoked //was the login failure handler actually invoked?
95+
assertFalse customLogoutHandler.invoked
96+
97+
mvc.perform(SecurityMockMvcLoginRequestBuilder.formLogin().login(account.getEmail()).password(password)).andExpect(authenticated())
98+
99+
assertTrue customLoginSuccessHandler.invoked //was the login success handler actually invoked?
100+
101+
mvc.perform(logout())
102+
103+
assertTrue customLogoutHandler.invoked //was the logout handler actually invoked?
104+
}
105+
106+
107+
}

extensions/spring/stormpath-spring-security-webmvc/src/test/groovy/com/stormpath/spring/config/StormpathAuthenticationFailureHandlerTest.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/*
2+
* Copyright 2016 Stormpath, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package com.stormpath.spring.config
217

318
import com.stormpath.sdk.servlet.authc.FailedAuthenticationRequestEvent

extensions/spring/stormpath-spring-security-webmvc/src/test/java/com/stormpath/spring/config/SecurityMockMvcLoginRequestBuilder.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
1+
/*
2+
* Copyright 2016 Stormpath, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package com.stormpath.spring.config;
217

318
import org.springframework.http.MediaType;
419
import org.springframework.mock.web.MockHttpServletRequest;
520
import org.springframework.test.web.servlet.RequestBuilder;
21+
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
622
import org.springframework.test.web.servlet.request.RequestPostProcessor;
723

824
import javax.servlet.ServletContext;
@@ -17,14 +33,21 @@ public static FormLoginRequestBuilder formLogin() {
1733
}
1834

1935
static final class FormLoginRequestBuilder implements RequestBuilder {
36+
private String username = "user";
37+
private String login = "null";
2038
private String password = "password";
2139
private RequestPostProcessor postProcessor = csrf();
2240

2341
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
24-
MockHttpServletRequest request = post("/login")
25-
.param("username", "user").param("password", password)
26-
.accept(MediaType.APPLICATION_FORM_URLENCODED)
27-
.buildRequest(servletContext);
42+
MockHttpServletRequestBuilder builder = post("/login")
43+
.param("password", password)
44+
.accept(MediaType.APPLICATION_FORM_URLENCODED);
45+
if (username == null) {
46+
builder.param("login", login);
47+
} else {
48+
builder.param("username", username);
49+
}
50+
MockHttpServletRequest request = builder.buildRequest(servletContext);
2851
return postProcessor.postProcessRequest(request);
2952
}
3053

@@ -33,6 +56,20 @@ public FormLoginRequestBuilder password(String password) {
3356
return this;
3457
}
3558

59+
//username and login are mutually exclusive. When Stormpath is in place the param name is 'login', but in SpringSec it is called 'username' by default
60+
public FormLoginRequestBuilder username(String username) {
61+
this.login = null;
62+
this.username = username;
63+
return this;
64+
}
65+
66+
//username and login are mutually exclusive. When Stormpath is in place the param name is 'login', but in SpringSec it is called 'username' by default
67+
public FormLoginRequestBuilder login(String login) {
68+
this.username = null;
69+
this.login = login;
70+
return this;
71+
}
72+
3673
private FormLoginRequestBuilder() {
3774
}
3875
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# Copyright 2016 Stormpath, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
stormpath.web.csrf.token.enabled = false

0 commit comments

Comments
 (0)