4 changed files with 1028 additions and 908 deletions
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2013 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 |
||||
* |
||||
* https://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.security.config.annotation.web.configurers; |
||||
|
||||
import org.springframework.context.ApplicationListener; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.security.access.event.AuthorizedEvent; |
||||
import org.springframework.security.config.annotation.ObjectPostProcessor; |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; |
||||
|
||||
@EnableWebSecurity |
||||
public class AuthorizedRequestsWithPostProcessorConfig extends |
||||
WebSecurityConfigurerAdapter { |
||||
static ApplicationListener<AuthorizedEvent> AL; |
||||
|
||||
// @formatter:off
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.anyRequest().permitAll() |
||||
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { |
||||
public <O extends FilterSecurityInterceptor> O postProcess( |
||||
O fsi) { |
||||
fsi.setPublishAuthorizationSuccess(true); |
||||
return fsi; |
||||
} |
||||
}); |
||||
} |
||||
// @formatter:on
|
||||
|
||||
@Bean |
||||
public ApplicationListener<AuthorizedEvent> applicationListener() { |
||||
return AL; |
||||
} |
||||
} |
||||
@ -1,162 +0,0 @@
@@ -1,162 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2013 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 |
||||
* |
||||
* https://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.security.config.annotation.web.configurers; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.security.access.AccessDecisionVoter; |
||||
import org.springframework.security.access.expression.SecurityExpressionHandler; |
||||
import org.springframework.security.access.expression.SecurityExpressionOperations; |
||||
import org.springframework.security.access.vote.AffirmativeBased; |
||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl; |
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.web.FilterInvocation; |
||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; |
||||
import org.springframework.security.web.access.expression.WebExpressionVoter; |
||||
import org.springframework.security.web.access.expression.WebSecurityExpressionRoot; |
||||
|
||||
/** |
||||
* |
||||
* @author Rob Winch |
||||
* |
||||
*/ |
||||
public class ExpressionUrlAuthorizationConfigurerConfigs { |
||||
|
||||
/** |
||||
* Ensure that All additional properties properly compile and chain properly |
||||
*/ |
||||
@EnableWebSecurity |
||||
static class AllPropertiesWorkConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
// @formatter:off
|
||||
@SuppressWarnings("rawtypes") |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
SecurityExpressionHandler<FilterInvocation> handler = new DefaultWebSecurityExpressionHandler(); |
||||
WebExpressionVoter expressionVoter = new WebExpressionVoter(); |
||||
AffirmativeBased adm = new AffirmativeBased(Arrays.<AccessDecisionVoter<? extends Object>>asList(expressionVoter)); |
||||
http |
||||
.authorizeRequests() |
||||
.expressionHandler(handler) |
||||
.accessDecisionManager(adm) |
||||
.filterSecurityInterceptorOncePerRequest(true) |
||||
.antMatchers("/a", "/b").hasRole("ADMIN") |
||||
.anyRequest().permitAll() |
||||
.and() |
||||
.formLogin(); |
||||
} |
||||
// @formatter:on
|
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class UseBeansInExpressions extends WebSecurityConfigurerAdapter { |
||||
|
||||
// @formatter:off
|
||||
@Autowired |
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER"); |
||||
} |
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.antMatchers("/admin/**").hasRole("ADMIN") |
||||
.antMatchers("/user/**").hasRole("USER") |
||||
.antMatchers("/allow/**").access("@permission.check(authentication,'user')") |
||||
.anyRequest().access("@permission.check(authentication,'admin')"); |
||||
} |
||||
// @formatter:on
|
||||
|
||||
@Bean |
||||
public Checker permission() { |
||||
return new Checker(); |
||||
} |
||||
|
||||
static class Checker { |
||||
public boolean check(Authentication authentication, String customArg) { |
||||
return authentication.getName().contains(customArg); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class CustomExpressionRootConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
// @formatter:off
|
||||
@Autowired |
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER"); |
||||
} |
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.expressionHandler(expressionHandler()) |
||||
.antMatchers("/admin/**").hasRole("ADMIN") |
||||
.antMatchers("/user/**").hasRole("USER") |
||||
.antMatchers("/allow/**").access("check('user')") |
||||
.anyRequest().access("check('admin')"); |
||||
} |
||||
// @formatter:on
|
||||
|
||||
@Bean |
||||
public CustomExpressionHandler expressionHandler() { |
||||
return new CustomExpressionHandler(); |
||||
} |
||||
|
||||
static class CustomExpressionHandler extends DefaultWebSecurityExpressionHandler { |
||||
|
||||
@Override |
||||
protected SecurityExpressionOperations createSecurityExpressionRoot( |
||||
Authentication authentication, FilterInvocation fi) { |
||||
WebSecurityExpressionRoot root = new CustomExpressionRoot(authentication, |
||||
fi); |
||||
root.setPermissionEvaluator(getPermissionEvaluator()); |
||||
root.setTrustResolver(new AuthenticationTrustResolverImpl()); |
||||
root.setRoleHierarchy(getRoleHierarchy()); |
||||
return root; |
||||
} |
||||
} |
||||
|
||||
static class CustomExpressionRoot extends WebSecurityExpressionRoot { |
||||
|
||||
public CustomExpressionRoot(Authentication a, FilterInvocation fi) { |
||||
super(a, fi); |
||||
} |
||||
|
||||
public boolean check(String customArg) { |
||||
Authentication auth = this.getAuthentication(); |
||||
return auth.getName().contains(customArg); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,694 +0,0 @@
@@ -1,694 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2016 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 |
||||
* |
||||
* https://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.security.config.annotation.web.configurers |
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
||||
|
||||
import static org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurerConfigs.* |
||||
|
||||
import javax.servlet.http.HttpServletResponse |
||||
|
||||
import org.springframework.beans.BeansException |
||||
import org.springframework.beans.factory.BeanCreationException |
||||
import org.springframework.beans.factory.config.BeanPostProcessor |
||||
import org.springframework.context.ApplicationListener |
||||
import org.springframework.context.annotation.Bean |
||||
import org.springframework.security.access.AccessDecisionManager; |
||||
import org.springframework.security.access.PermissionEvaluator |
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy |
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl |
||||
import org.springframework.security.access.event.AuthorizedEvent |
||||
import org.springframework.security.access.vote.AffirmativeBased |
||||
import org.springframework.security.authentication.RememberMeAuthenticationToken |
||||
import org.springframework.security.config.annotation.BaseSpringSpec |
||||
import org.springframework.security.config.annotation.SecurityExpressions.* |
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter |
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurerConfigs.CustomExpressionRootConfig |
||||
import org.springframework.security.core.Authentication |
||||
import org.springframework.security.core.authority.AuthorityUtils |
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor |
||||
|
||||
public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { |
||||
|
||||
def "hasAnyAuthority('ROLE_USER')"() { |
||||
when: |
||||
def expression = ExpressionUrlAuthorizationConfigurer.hasAnyAuthority("ROLE_USER") |
||||
then: |
||||
expression == "hasAnyAuthority('ROLE_USER')" |
||||
} |
||||
|
||||
def "hasAnyAuthority('ROLE_USER','ROLE_ADMIN')"() { |
||||
when: |
||||
def expression = ExpressionUrlAuthorizationConfigurer.hasAnyAuthority("ROLE_USER","ROLE_ADMIN") |
||||
then: |
||||
expression == "hasAnyAuthority('ROLE_USER','ROLE_ADMIN')" |
||||
} |
||||
|
||||
def "hasAnyRole('USER')"() { |
||||
when: |
||||
def expression = ExpressionUrlAuthorizationConfigurer.hasAnyRole("USER") |
||||
then: |
||||
expression == "hasAnyRole('ROLE_USER')" |
||||
} |
||||
|
||||
def "hasAnyRole('USER','ADMIN')"() { |
||||
when: |
||||
def expression = ExpressionUrlAuthorizationConfigurer.hasAnyRole("USER","ADMIN") |
||||
then: |
||||
expression == "hasAnyRole('ROLE_USER','ROLE_ADMIN')" |
||||
} |
||||
|
||||
def "hasRole('ROLE_USER') is rejected due to starting with ROLE_"() { |
||||
when: |
||||
def expression = ExpressionUrlAuthorizationConfigurer.hasRole("ROLE_USER") |
||||
then: |
||||
IllegalArgumentException e = thrown() |
||||
e.message == "role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_USER'" |
||||
} |
||||
|
||||
def "authorizeRequests() uses AffirmativeBased AccessDecisionManager"() { |
||||
when: "Load Config with no specific AccessDecisionManager" |
||||
loadConfig(NoSpecificAccessDecessionManagerConfig) |
||||
then: "AccessDecessionManager matches the HttpSecurityBuilder's default" |
||||
findFilter(FilterSecurityInterceptor).accessDecisionManager.class == AffirmativeBased |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NoSpecificAccessDecessionManagerConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.anyRequest().hasRole("USER") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() no requests"() { |
||||
when: "Load Config with no requests" |
||||
loadConfig(NoRequestsConfig) |
||||
then: "A meaningful exception is thrown" |
||||
BeanCreationException success = thrown() |
||||
success.message.contains "At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())" |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NoRequestsConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() incomplete mapping"() { |
||||
when: "Load Config with incomplete mapping" |
||||
loadConfig(IncompleteMappingConfig) |
||||
then: "A meaningful exception is thrown" |
||||
BeanCreationException success = thrown() |
||||
success.message.contains "An incomplete mapping was found for " |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class IncompleteMappingConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.antMatchers("/a").authenticated() |
||||
.anyRequest() |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() hasAuthority"() { |
||||
setup: |
||||
loadConfig(HasAuthorityConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
login() |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login("user","ROLE_INVALID") |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class HasAuthorityConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().hasAuthority("ROLE_USER") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() hasAnyAuthority"() { |
||||
setup: |
||||
loadConfig(HasAnyAuthorityConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
login("user","ROLE_ADMIN") |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login("user","ROLE_DBA") |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login("user","ROLE_INVALID") |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class HasAnyAuthorityConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().hasAnyAuthority("ROLE_ADMIN","ROLE_DBA") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() hasIpAddress"() { |
||||
setup: |
||||
loadConfig(HasIpAddressConfig) |
||||
when: |
||||
request.remoteAddr = "192.168.1.1" |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
request.remoteAddr = "192.168.1.0" |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class HasIpAddressConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().hasIpAddress("192.168.1.0") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() anonymous"() { |
||||
setup: |
||||
loadConfig(AnonymousConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login() |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class AnonymousConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().anonymous() |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() rememberMe"() { |
||||
setup: |
||||
loadConfig(RememberMeConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class RememberMeConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.rememberMe() |
||||
.and() |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().rememberMe() |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() denyAll"() { |
||||
setup: |
||||
loadConfig(DenyAllConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
login(new UsernamePasswordAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class DenyAllConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().denyAll() |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() not denyAll"() { |
||||
setup: |
||||
loadConfig(NotDenyAllConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NotDenyAllConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().not().denyAll() |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() fullyAuthenticated"() { |
||||
setup: |
||||
loadConfig(FullyAuthenticatedConfig) |
||||
when: |
||||
super.setup() |
||||
login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
when: |
||||
super.setup() |
||||
login() |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == HttpServletResponse.SC_OK |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class FullyAuthenticatedConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.rememberMe() |
||||
.and() |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().fullyAuthenticated() |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER") |
||||
} |
||||
} |
||||
|
||||
def "authorizeRequests() access"() { |
||||
setup: |
||||
loadConfig(AccessConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: "Access is granted due to GET" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
login() |
||||
request.method = "POST" |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: "Access is granted due to role" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: |
||||
super.setup() |
||||
request.method = "POST" |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: "Access is denied" |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class AccessConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.rememberMe() |
||||
.and() |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().access("hasRole('ROLE_USER') or request.method == 'GET'") |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER") |
||||
} |
||||
} |
||||
|
||||
|
||||
def "invoke authorizeUrls twice does not reset"() { |
||||
setup: |
||||
loadConfig(InvokeTwiceDoesNotResetConfig) |
||||
when: |
||||
request.method = "POST" |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: "Access is denied" |
||||
response.status == HttpServletResponse.SC_UNAUTHORIZED |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class InvokeTwiceDoesNotResetConfig extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.httpBasic() |
||||
.and() |
||||
.authorizeRequests() |
||||
.anyRequest().authenticated() |
||||
.and() |
||||
.authorizeRequests() |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
} |
||||
} |
||||
|
||||
def "All Properties are accessible and chain properly"() { |
||||
when: |
||||
loadConfig(AllPropertiesWorkConfig) |
||||
then: |
||||
noExceptionThrown() |
||||
} |
||||
|
||||
def "AuthorizedRequests withPostProcessor"() { |
||||
setup: |
||||
ApplicationListener al = Mock() |
||||
AuthorizedRequestsWithPostProcessorConfig.AL = al |
||||
loadConfig(AuthorizedRequestsWithPostProcessorConfig) |
||||
when: |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: |
||||
1 * al.onApplicationEvent(_ as AuthorizedEvent) |
||||
} |
||||
|
||||
def "Use @permission.check in access"() { |
||||
setup: |
||||
loadConfig(UseBeansInExpressions) |
||||
when: "invoke standard expression that denies access" |
||||
login() |
||||
request.servletPath = "/admin/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "standard expression works - get forbidden" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
when: "invoke standard expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/user/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "standard expression works - get ok" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke custom bean as expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/allow/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "custom bean expression allows access" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke custom bean as expression that denies access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/deny/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "custom bean expression denies access" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
def "Use custom expressionroot in access"() { |
||||
setup: |
||||
loadConfig(CustomExpressionRootConfig) |
||||
when: "invoke standard expression that denies access" |
||||
login() |
||||
request.servletPath = "/admin/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "standard expression works - get forbidden" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
when: "invoke standard expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/user/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "standard expression works - get ok" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke custom bean as expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/allow/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "custom bean expression allows access" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke custom bean as expression that denies access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/deny/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "custom bean expression denies access" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
def "SEC-3011: Default AccessDecisionManager postProcessed"() { |
||||
when: |
||||
loadConfig(Sec3011Config) |
||||
then: |
||||
context.getBean(MockBeanPostProcessor).beans.find { it instanceof AccessDecisionManager } |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class Sec3011Config extends WebSecurityConfigurerAdapter { |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.anyRequest().authenticated(); |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication(); |
||||
} |
||||
|
||||
@Bean |
||||
static MockBeanPostProcessor mbpp() { |
||||
return new MockBeanPostProcessor(); |
||||
} |
||||
} |
||||
|
||||
static class MockBeanPostProcessor implements BeanPostProcessor { |
||||
List<Object> beans = new ArrayList<Object>(); |
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, |
||||
String beanName) throws BeansException { |
||||
beans.add(bean); |
||||
return bean; |
||||
} |
||||
|
||||
public Object postProcessAfterInitialization(Object bean, |
||||
String beanName) throws BeansException { |
||||
|
||||
return bean; |
||||
} |
||||
|
||||
} |
||||
|
||||
def "permissionEvaluator autowired"() { |
||||
setup: |
||||
loadConfig(PermissionEvaluatorConfig) |
||||
when: "invoke hasPermission expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/allow/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with id and type works - allows access" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke hasPermission expression that denies access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/deny/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with id and type works - denies access" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
when: "invoke hasPermission expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/allowObject/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with object works - allows access" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke hasPermission expression that denies access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/denyObject/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with object works - denies access" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class PermissionEvaluatorConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.antMatchers("/allow/**").access("hasPermission('ID', 'TYPE', 'PERMISSION')") |
||||
.antMatchers("/allowObject/**").access("hasPermission('TESTOBJ', 'PERMISSION')") |
||||
.antMatchers("/deny/**").access("hasPermission('ID', 'TYPE', 'NO PERMISSION')") |
||||
.antMatchers("/denyObject/**").access("hasPermission('TESTOBJ', 'NO PERMISSION')") |
||||
.anyRequest().permitAll(); |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER") |
||||
} |
||||
|
||||
@Bean |
||||
public PermissionEvaluator permissionEvaluator(){ |
||||
return new PermissionEvaluator(){ |
||||
@Override |
||||
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { |
||||
return "TESTOBJ".equals(targetDomainObject) && "PERMISSION".equals(permission); |
||||
} |
||||
@Override |
||||
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, |
||||
Object permission) { |
||||
return "ID".equals(targetId) && "TYPE".equals(targetType) && "PERMISSION".equals(permission); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class RoleHierarchyConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.antMatchers("/allow/**").access("hasRole('XXX')") |
||||
.antMatchers("/deny/**").access("hasRole('NOPE')") |
||||
.anyRequest().permitAll(); |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER") |
||||
} |
||||
|
||||
@Bean |
||||
public RoleHierarchy roleHierarchy(){ |
||||
return new RoleHierarchyImpl("USER > XXX"); |
||||
} |
||||
|
||||
} |
||||
|
||||
def "roleHierarchy autowired"() { |
||||
setup: |
||||
loadConfig(PermissionEvaluatorConfig) |
||||
when: "invoke roleHierarchy expression that allows access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/allow/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with id and type works - allows access" |
||||
response.status == HttpServletResponse.SC_OK |
||||
when: "invoke roleHierarchy expression that denies access" |
||||
super.setup() |
||||
login() |
||||
request.servletPath = "/deny/1" |
||||
springSecurityFilterChain.doFilter(request, response, chain) |
||||
then: "permissionEvaluator with id and type works - denies access" |
||||
response.status == HttpServletResponse.SC_FORBIDDEN |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue