Browse Source
* Move GrantedAuthorityDefaults to config module * Move setting of default role into config module vs ApplicationContextAware Issue gh-3701pull/4053/head
24 changed files with 685 additions and 336 deletions
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
/* |
||||
* Copyright 2012-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 |
||||
* |
||||
* 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.security.config.http; |
||||
|
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.context.ApplicationContextAware; |
||||
import org.springframework.security.config.core.GrantedAuthorityDefaults; |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
* @since 4.2 |
||||
*/ |
||||
class GrantedAuthorityDefaultsParserUtils { |
||||
|
||||
|
||||
static RootBeanDefinition registerWithDefaultRolePrefix(ParserContext pc, Class<? extends AbstractGrantedAuthorityDefaultsBeanFactory> beanFactoryClass) { |
||||
RootBeanDefinition beanFactoryDefinition = new RootBeanDefinition(beanFactoryClass); |
||||
String beanFactoryRef = pc.getReaderContext().generateBeanName(beanFactoryDefinition); |
||||
pc.getRegistry().registerBeanDefinition(beanFactoryRef, beanFactoryDefinition); |
||||
|
||||
RootBeanDefinition bean = new RootBeanDefinition(); |
||||
bean.setFactoryBeanName(beanFactoryRef); |
||||
bean.setFactoryMethodName("getBean"); |
||||
return bean; |
||||
} |
||||
|
||||
static abstract class AbstractGrantedAuthorityDefaultsBeanFactory implements ApplicationContextAware { |
||||
protected String rolePrefix = "ROLE_"; |
||||
|
||||
@Override |
||||
public final void setApplicationContext(ApplicationContext applicationContext) |
||||
throws BeansException { |
||||
String[] grantedAuthorityDefaultsBeanNames = applicationContext.getBeanNamesForType(GrantedAuthorityDefaults.class); |
||||
if(grantedAuthorityDefaultsBeanNames.length == 1) { |
||||
GrantedAuthorityDefaults grantedAuthorityDefaults = applicationContext.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class); |
||||
this.rolePrefix = grantedAuthorityDefaults.getRolePrefix(); |
||||
} |
||||
} |
||||
|
||||
abstract Object getBean(); |
||||
} |
||||
|
||||
private GrantedAuthorityDefaultsParserUtils() {} |
||||
} |
||||
@ -0,0 +1,183 @@
@@ -0,0 +1,183 @@
|
||||
/* |
||||
* 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 |
||||
* |
||||
* 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.security.config.core; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.mock.web.MockFilterChain; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.authentication.TestingAuthenticationToken; |
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; |
||||
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.context.SecurityContext; |
||||
import org.springframework.security.core.context.SecurityContextHolder; |
||||
import org.springframework.security.web.FilterChainProxy; |
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; |
||||
import org.springframework.test.context.ContextConfiguration; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@ContextConfiguration |
||||
public class GrantedAuthorityDefaultsJcTests { |
||||
@Autowired |
||||
FilterChainProxy springSecurityFilterChain; |
||||
@Autowired |
||||
MessageService messageService; |
||||
|
||||
MockHttpServletRequest request; |
||||
MockHttpServletResponse response; |
||||
MockFilterChain chain; |
||||
|
||||
@Before |
||||
public void setup() { |
||||
setup("USER"); |
||||
|
||||
request = new MockHttpServletRequest(); |
||||
request.setMethod("GET"); |
||||
response = new MockHttpServletResponse(); |
||||
chain = new MockFilterChain(); |
||||
} |
||||
|
||||
@After |
||||
public void cleanup() { |
||||
SecurityContextHolder.clearContext(); |
||||
} |
||||
|
||||
@Test |
||||
public void doFilter() throws Exception { |
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); |
||||
} |
||||
|
||||
@Test |
||||
public void doFilterDenied() throws Exception { |
||||
setup("DENIED"); |
||||
|
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); |
||||
} |
||||
|
||||
@Test |
||||
public void message() { |
||||
messageService.getMessage(); |
||||
} |
||||
|
||||
@Test |
||||
public void jsrMessage() { |
||||
messageService.getJsrMessage(); |
||||
} |
||||
|
||||
@Test(expected = AccessDeniedException.class) |
||||
public void messageDenied() { |
||||
setup("DENIED"); |
||||
|
||||
messageService.getMessage(); |
||||
} |
||||
|
||||
@Test(expected = AccessDeniedException.class) |
||||
public void jsrMessageDenied() { |
||||
setup("DENIED"); |
||||
|
||||
messageService.getJsrMessage(); |
||||
} |
||||
|
||||
// SEC-2926
|
||||
@Test |
||||
public void doFilterIsUserInRole() throws Exception { |
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
chain = new MockFilterChain() { |
||||
|
||||
@Override |
||||
public void doFilter(ServletRequest request, ServletResponse response) |
||||
throws IOException, ServletException { |
||||
HttpServletRequest httpRequest = (HttpServletRequest) request; |
||||
assertThat(httpRequest.isUserInRole("USER")).isTrue(); |
||||
assertThat(httpRequest.isUserInRole("INVALID")).isFalse(); |
||||
super.doFilter(request, response); |
||||
} |
||||
|
||||
}; |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(chain.getRequest()).isNotNull(); |
||||
} |
||||
|
||||
private void setup(String role) { |
||||
TestingAuthenticationToken user = new TestingAuthenticationToken("user", "password", role); |
||||
SecurityContextHolder.getContext().setAuthentication(user); |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableWebSecurity |
||||
@EnableGlobalMethodSecurity(prePostEnabled=true, jsr250Enabled=true) |
||||
static class Config extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Autowired |
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { |
||||
auth |
||||
.inMemoryAuthentication() |
||||
.withUser("user").password("password").roles("USER"); |
||||
} |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.authorizeRequests() |
||||
.anyRequest().access("hasRole('USER')"); |
||||
} |
||||
|
||||
@Bean |
||||
public MessageService messageService() { |
||||
return new HelloWorldMessageService(); |
||||
} |
||||
|
||||
@Bean |
||||
public static GrantedAuthorityDefaults grantedAuthorityDefaults() { |
||||
return new GrantedAuthorityDefaults(""); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,146 @@
@@ -0,0 +1,146 @@
|
||||
/* |
||||
* 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 |
||||
* |
||||
* 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.security.config.core; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.mock.web.MockFilterChain; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.authentication.TestingAuthenticationToken; |
||||
import org.springframework.security.core.context.SecurityContext; |
||||
import org.springframework.security.core.context.SecurityContextHolder; |
||||
import org.springframework.security.web.FilterChainProxy; |
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; |
||||
import org.springframework.test.context.ContextConfiguration; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@ContextConfiguration |
||||
public class GrantedAuthorityDefaultsXmlTests { |
||||
@Autowired |
||||
FilterChainProxy springSecurityFilterChain; |
||||
@Autowired |
||||
MessageService messageService; |
||||
|
||||
MockHttpServletRequest request; |
||||
MockHttpServletResponse response; |
||||
MockFilterChain chain; |
||||
|
||||
@Before |
||||
public void setup() { |
||||
setup("USER"); |
||||
|
||||
request = new MockHttpServletRequest(); |
||||
request.setMethod("GET"); |
||||
response = new MockHttpServletResponse(); |
||||
chain = new MockFilterChain(); |
||||
} |
||||
|
||||
@After |
||||
public void cleanup() { |
||||
SecurityContextHolder.clearContext(); |
||||
} |
||||
|
||||
@Test |
||||
public void doFilter() throws Exception { |
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); |
||||
} |
||||
|
||||
@Test |
||||
public void doFilterDenied() throws Exception { |
||||
setup("DENIED"); |
||||
|
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); |
||||
} |
||||
|
||||
@Test |
||||
public void message() { |
||||
messageService.getMessage(); |
||||
} |
||||
|
||||
@Test |
||||
public void jsrMessage() { |
||||
messageService.getJsrMessage(); |
||||
} |
||||
|
||||
@Test(expected = AccessDeniedException.class) |
||||
public void messageDenied() { |
||||
setup("DENIED"); |
||||
|
||||
messageService.getMessage(); |
||||
} |
||||
|
||||
@Test(expected = AccessDeniedException.class) |
||||
public void jsrMessageDenied() { |
||||
setup("DENIED"); |
||||
|
||||
messageService.getJsrMessage(); |
||||
} |
||||
|
||||
// SEC-2926
|
||||
@Test |
||||
public void doFilterIsUserInRole() throws Exception { |
||||
SecurityContext context = SecurityContextHolder.getContext(); |
||||
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); |
||||
|
||||
chain = new MockFilterChain() { |
||||
|
||||
@Override |
||||
public void doFilter(ServletRequest request, ServletResponse response) |
||||
throws IOException, ServletException { |
||||
HttpServletRequest httpRequest = (HttpServletRequest) request; |
||||
assertThat(httpRequest.isUserInRole("USER")).isTrue(); |
||||
assertThat(httpRequest.isUserInRole("INVALID")).isFalse(); |
||||
super.doFilter(request, response); |
||||
} |
||||
|
||||
}; |
||||
|
||||
springSecurityFilterChain.doFilter(request, response, chain); |
||||
|
||||
assertThat(chain.getRequest()).isNotNull(); |
||||
} |
||||
|
||||
private void setup(String role) { |
||||
TestingAuthenticationToken user = new TestingAuthenticationToken("user", "password", role); |
||||
SecurityContextHolder.getContext().setAuthentication(user); |
||||
} |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/* |
||||
* 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 |
||||
* |
||||
* 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.security.config.core; |
||||
|
||||
import javax.annotation.security.RolesAllowed; |
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize; |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
*/ |
||||
public class HelloWorldMessageService implements MessageService { |
||||
|
||||
@PreAuthorize("hasRole('USER')") |
||||
public String getMessage() { |
||||
return "Hello World"; |
||||
} |
||||
|
||||
@RolesAllowed("USER") |
||||
public String getJsrMessage() { |
||||
return "Hello JSR"; |
||||
} |
||||
} |
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
/* |
||||
* 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 |
||||
* |
||||
* 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.security.config.core; |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
*/ |
||||
public interface MessageService { |
||||
String getMessage(); |
||||
String getJsrMessage(); |
||||
} |
||||
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xmlns="http://www.springframework.org/schema/security" |
||||
xmlns:c="http://www.springframework.org/schema/c" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> |
||||
|
||||
<http use-expressions="true"> |
||||
<intercept-url access="hasRole('USER')" pattern="/**" /> |
||||
<form-login/> |
||||
<logout/> |
||||
</http> |
||||
|
||||
<authentication-manager> |
||||
<authentication-provider> |
||||
<user-service> |
||||
<user name="user" password="password" authorities="USER"/> |
||||
<user name="admin" password="password" authorities="USER,ADMIN"/> |
||||
</user-service> |
||||
</authentication-provider> |
||||
</authentication-manager> |
||||
|
||||
<global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled"/> |
||||
|
||||
<b:bean class="org.springframework.security.config.core.HelloWorldMessageService"/> |
||||
<b:bean class="org.springframework.security.config.core.GrantedAuthorityDefaults" |
||||
c:rolePrefix=""/> |
||||
</b:beans> |
||||
@ -1,60 +0,0 @@
@@ -1,60 +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 |
||||
* |
||||
* 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.security.ldap.userdetails; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.ldap.core.ContextSource; |
||||
import org.springframework.security.config.GrantedAuthorityDefaults; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* @author Eddú Meléndez |
||||
*/ |
||||
public class DefaultLdapAuthoritiesPopulatorTests { |
||||
|
||||
@Test |
||||
public void testDefaultRolePrefix() { |
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
||||
context.register(LdapAuthoritiesPopulatorConfiguration.class); |
||||
context.refresh(); |
||||
|
||||
DefaultLdapAuthoritiesPopulator ldapPopulator = context.getBean(DefaultLdapAuthoritiesPopulator.class); |
||||
assertThat(ldapPopulator.getRolePrefix()).isEqualTo("ROL_"); |
||||
} |
||||
|
||||
@Configuration |
||||
static class LdapAuthoritiesPopulatorConfiguration { |
||||
|
||||
@Bean |
||||
public GrantedAuthorityDefaults authorityDefaults() { |
||||
return new GrantedAuthorityDefaults("ROL_"); |
||||
} |
||||
|
||||
@Bean |
||||
public DefaultLdapAuthoritiesPopulator ldapAuthoritiesPopulator() { |
||||
ContextSource contextSource = mock(ContextSource.class); |
||||
return new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups"); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue