Skip to content

Commit 112480a

Browse files
committed
Fixes spring-attic#226 - Configure filterProcessesUrl via SpringSocialConfigurer
- Add the ability to configure filterProcessesUrl of SocialAuthentication via SpringSocialConfigurer - Add SpringSocialConfigurer#configure test
1 parent 7934198 commit 112480a

File tree

2 files changed

+141
-20
lines changed

2 files changed

+141
-20
lines changed

spring-social-security/src/main/java/org/springframework/social/security/SpringSocialConfigurer.java

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
/**
3030
* Configurer that adds {@link SocialAuthenticationFilter} to Spring Security's filter chain.
3131
* Used with Spring Security 3.2's Java-based configuration support, when overriding WebSecurityConfigurerAdapter#configure(HttpSecurity):
32-
*
32+
*
3333
* <pre>
3434
* protected void configure(HttpSecurity http) throws Exception {
3535
* http.
@@ -38,21 +38,23 @@
3838
* .apply(new SpringSocialConfigurer());
3939
* }
4040
* </pre>
41-
*
41+
*
4242
* @author Craig Walls
4343
*/
4444
public class SpringSocialConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
4545

4646
private UserIdSource userIdSource;
47-
47+
4848
private String postLoginUrl;
49-
49+
5050
private String postFailureUrl;
5151

5252
private String signupUrl;
5353

5454
private String connectionAddedRedirectUrl;
5555

56+
private String filterProcessesUrl;
57+
5658
private boolean alwaysUsePostLoginUrl = false;
5759

5860
/**
@@ -62,30 +64,30 @@ public class SpringSocialConfigurer extends SecurityConfigurerAdapter<DefaultSec
6264
*/
6365
public SpringSocialConfigurer() {
6466
}
65-
67+
6668
@Override
67-
public void configure(HttpSecurity http) throws Exception {
69+
public void configure(HttpSecurity http) throws Exception {
6870
ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
6971
UsersConnectionRepository usersConnectionRepository = getDependency(applicationContext, UsersConnectionRepository.class);
7072
SocialAuthenticationServiceLocator authServiceLocator = getDependency(applicationContext, SocialAuthenticationServiceLocator.class);
7173
SocialUserDetailsService socialUsersDetailsService = getDependency(applicationContext, SocialUserDetailsService.class);
72-
74+
7375
SocialAuthenticationFilter filter = new SocialAuthenticationFilter(
74-
http.getSharedObject(AuthenticationManager.class),
75-
userIdSource != null ? userIdSource : new AuthenticationNameUserIdSource(),
76-
usersConnectionRepository,
76+
http.getSharedObject(AuthenticationManager.class),
77+
userIdSource != null ? userIdSource : new AuthenticationNameUserIdSource(),
78+
usersConnectionRepository,
7779
authServiceLocator);
78-
80+
7981
RememberMeServices rememberMe = http.getSharedObject(RememberMeServices.class);
8082
if (rememberMe != null) {
8183
filter.setRememberMeServices(rememberMe);
8284
}
83-
85+
8486
if (postLoginUrl != null) {
8587
filter.setPostLoginUrl(postLoginUrl);
8688
filter.setAlwaysUsePostLoginUrl(alwaysUsePostLoginUrl);
8789
}
88-
90+
8991
if (postFailureUrl != null) {
9092
filter.setPostFailureUrl(postFailureUrl);
9193
}
@@ -97,7 +99,11 @@ public void configure(HttpSecurity http) throws Exception {
9799
if (connectionAddedRedirectUrl != null) {
98100
filter.setConnectionAddedRedirectUrl(connectionAddedRedirectUrl);
99101
}
100-
102+
103+
if (filterProcessesUrl != null) {
104+
filter.setFilterProcessesUrl(filterProcessesUrl);
105+
}
106+
101107
http.authenticationProvider(
102108
new SocialAuthenticationProvider(usersConnectionRepository, socialUsersDetailsService))
103109
.addFilterBefore(postProcess(filter), AbstractPreAuthenticatedProcessingFilter.class);
@@ -111,7 +117,7 @@ private <T> T getDependency(ApplicationContext applicationContext, Class<T> depe
111117
throw new IllegalStateException("SpringSocialConfigurer depends on " + dependencyType.getName() +". No single bean of that type found in application context.", e);
112118
}
113119
}
114-
120+
115121
/**
116122
* Sets the {@link UserIdSource} to use for authentication. Defaults to {@link AuthenticationNameUserIdSource}.
117123
* @param userIdSource the UserIdSource to use when authenticating
@@ -121,27 +127,27 @@ public SpringSocialConfigurer userIdSource(UserIdSource userIdSource) {
121127
this.userIdSource = userIdSource;
122128
return this;
123129
}
124-
130+
125131
/**
126132
* Sets the URL to land on after a successful login.
127133
* @param postLoginUrl the URL to redirect to after a successful login
128-
* @return this SpringSocialConfigurer for chained configuration
134+
* @return this SpringSocialConfigurer for chained configuration
129135
*/
130136
public SpringSocialConfigurer postLoginUrl(String postLoginUrl) {
131137
this.postLoginUrl = postLoginUrl;
132138
return this;
133139
}
134-
140+
135141
/**
136142
* If true, always redirect to postLoginUrl, even if a pre-signin target is in the request cache.
137143
* @param alwaysUsePostLoginUrl if true, always redirect to the postLoginUrl
138-
* @return this SpringSocialConfigurer for chained configuration
144+
* @return this SpringSocialConfigurer for chained configuration
139145
*/
140146
public SpringSocialConfigurer alwaysUsePostLoginUrl(boolean alwaysUsePostLoginUrl) {
141147
this.alwaysUsePostLoginUrl = alwaysUsePostLoginUrl;
142148
return this;
143149
}
144-
150+
145151
/**
146152
* Sets the URL to redirect to if authentication fails or if authorization is denied by the user.
147153
* @param postFailureUrl the URL to redirect to after an authentication fail or authorization deny
@@ -172,4 +178,13 @@ public SpringSocialConfigurer connectionAddedRedirectUrl(String connectionAddedR
172178
return this;
173179
}
174180

181+
/**
182+
* Sets the URL that determines if social authentication is required.
183+
* @param filterProcessesUrl the URL that will initiate the social authentication process
184+
* @return this SpringSocialConfigurer for chained configuration
185+
*/
186+
public SpringSocialConfigurer filterProcessesUrl(String filterProcessesUrl) {
187+
this.filterProcessesUrl = filterProcessesUrl;
188+
return this;
189+
}
175190
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package org.springframework.social.security;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertNotNull;
5+
import static org.junit.Assert.assertSame;
6+
import static org.junit.Assert.assertTrue;
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
import static org.mockito.Mockito.mock;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.Configuration;
13+
import org.springframework.security.authentication.ProviderManager;
14+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
15+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
16+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
17+
import org.springframework.security.web.FilterChainProxy;
18+
import org.springframework.security.web.SecurityFilterChain;
19+
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
20+
import org.springframework.social.connect.UsersConnectionRepository;
21+
import org.springframework.test.context.junit4.SpringRunner;
22+
import org.springframework.test.util.ReflectionTestUtils;
23+
24+
/**
25+
* @author Florian Lopes
26+
*/
27+
@RunWith(SpringRunner.class)
28+
public class SpringSocialConfigurerTest {
29+
30+
@Autowired
31+
private FilterChainProxy springSecurityFilterChain;
32+
33+
@Autowired
34+
private UsersConnectionRepository usersConnectionRepository;
35+
36+
@Autowired
37+
private SocialAuthenticationServiceLocator socialAuthenticationServiceLocator;
38+
39+
@Test
40+
public void testConfigure() {
41+
final SecurityFilterChain defaultFilterChain = this.springSecurityFilterChain.getFilterChains().get(0);
42+
assertTrue(defaultFilterChain.getFilters().stream().anyMatch(filter -> filter instanceof SocialAuthenticationFilter));
43+
44+
final SocialAuthenticationFilter socialAuthenticationFilter =
45+
(SocialAuthenticationFilter) defaultFilterChain.getFilters()
46+
.stream().filter(filter -> filter instanceof SocialAuthenticationFilter).findFirst().orElse(null);
47+
assertNotNull(socialAuthenticationFilter);
48+
49+
assertTrue(ReflectionTestUtils.getField(socialAuthenticationFilter, "userIdSource") instanceof AuthenticationNameUserIdSource);
50+
51+
final ProviderManager providerManager =
52+
(ProviderManager) ReflectionTestUtils.getField(socialAuthenticationFilter, "authenticationManager");
53+
assertTrue(providerManager.getProviders().stream().anyMatch(authenticationProvider -> authenticationProvider instanceof SocialAuthenticationProvider));
54+
55+
assertNotNull(ReflectionTestUtils.getField(socialAuthenticationFilter, "rememberMeServices"));
56+
final SocialAuthenticationFailureHandler failureHandler =
57+
(SocialAuthenticationFailureHandler) ReflectionTestUtils.getField(socialAuthenticationFilter, "failureHandler");
58+
59+
assertEquals("/postFailure", ReflectionTestUtils.getField(failureHandler.getDelegate(), "defaultFailureUrl"));
60+
final AuthenticationSuccessHandler successHandler =
61+
(AuthenticationSuccessHandler) ReflectionTestUtils.getField(socialAuthenticationFilter, "successHandler");
62+
assertEquals("/postLogin", ReflectionTestUtils.getField(successHandler, "defaultTargetUrl"));
63+
assertEquals("/social-login", ReflectionTestUtils.getField(socialAuthenticationFilter, "filterProcessesUrl"));
64+
assertEquals("/connectionAdded", ReflectionTestUtils.getField(socialAuthenticationFilter, "connectionAddedRedirectUrl"));
65+
assertEquals("/signup", ReflectionTestUtils.getField(socialAuthenticationFilter, "signupUrl"));
66+
67+
assertSame(this.usersConnectionRepository, socialAuthenticationFilter.getUsersConnectionRepository());
68+
assertSame(this.socialAuthenticationServiceLocator, socialAuthenticationFilter.getAuthServiceLocator());
69+
}
70+
71+
@EnableWebSecurity
72+
@Configuration
73+
static class SpringSocialSecurityConfig extends WebSecurityConfigurerAdapter {
74+
75+
// @formatter:off
76+
@Override
77+
protected void configure(HttpSecurity http) throws Exception {
78+
http
79+
.rememberMe()
80+
.and()
81+
.apply(new SpringSocialConfigurer()
82+
.userIdSource(new AuthenticationNameUserIdSource())
83+
.postLoginUrl("/postLogin")
84+
.postFailureUrl("/postFailure")
85+
.signupUrl("/signup")
86+
.connectionAddedRedirectUrl("/connectionAdded")
87+
.filterProcessesUrl("/social-login"));
88+
}
89+
// @formatter:on
90+
91+
@Bean
92+
public UsersConnectionRepository usersConnectionRepository() {
93+
return mock(UsersConnectionRepository.class);
94+
}
95+
96+
@Bean
97+
public SocialUserDetailsService socialUserDetailsService() {
98+
return mock(SocialUserDetailsService.class);
99+
}
100+
101+
@Bean
102+
public SocialAuthenticationServiceLocator socialAuthenticationServiceLocator() {
103+
return mock(SocialAuthenticationServiceLocator.class);
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)