Evaluate Web Services Interceptor Before Spring Security Filter Chain - spring

I have a SOAP-based web services application which is leveraging Spring Web Services (and Spring WS Security) as well as Spring Security. I am using a custom AbstractWsSecurityInterceptor to authenticate the incoming requests (using an injected AuthenticationManager) and to add the successful authentications to the SecurityContext. I then have a custom AcessDecisionManager which is using a custom WebSecurityExpressionHandler to validate a certain property from the principal added to the context by the interceptor.
Below is an idea of what my configuration files look like:
SecurityConfig.java:
#Getter
#Setter
#Configuration
#RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AccessDecisionManager customAccessDecisionManager;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors()
.and().csrf().disable()
.authorizeRequests()
.accessDecisionManager(customAccessDecisionManager)
.antMatchers(GET, "/actuator/**").permitAll()
.anyRequest().access("customAccessMethod()")
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
WebServiceConfig.java:
#EnableWs
#Configuration
#RequiredArgsConstructor
public class WebServiceConfig extends WsConfigurerAdapter {
private final AuthenticationManager authenticationManager;
#Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(servlet, "/ws/*");
}
...
...
#Bean
AbstractWsSecurityInterceptor customAuthenticationInterceptor() {
return new CustomAuthenticationInterceptor(authenticationManager);
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(customAuthenticationInterceptor());
}
}
The issue with this setup is that the Spring Security filter chain is evaluated first and fails the authentication because the AccessDecisionManager is evaluated before the request has a chance to enter the custom AbstractWsSecurityInterceptor and place the authentication in the SecurityContext.
Is there any way to evaluate the interceptor and handling of the request on the Web Services and WS Security side of things before it then hits the Spring Security filter chain? Is this a possibility?
Thank you in advance for the help!

Related

Required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found. message from spring security

I am trying to implement one sample demo for Spring Security with Spring Boot for checking the authentication. I am trying to implement a basic workout for Spring Security and getting the following message,
Description:
Parameter 0 of constructor in com.spacestudy.service.CustomAuthenticationProvider required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.security.web.AuthenticationEntryPoint' in your configuration.
My security config class SecurityConfig.java,
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationEntryPoint authEntryPoint;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new ApplicationContextHeaderFilter((ApplicationContext) authenticationManager()));
}
}
And my BasicAuthenticationFilter implementation like the following,
#Component
public class CustomAuthenticationProvider extends BasicAuthenticationFilter {
public CustomAuthenticationProvider(AuthenticationManager authenticationManager) {
super(authenticationManager);
// TODO Auto-generated constructor stub
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String bearerToken = request.getHeader("accessToken");
String username = "test";
String password = "test";
if (username != null && !username.isEmpty()) {
return new UsernamePasswordAuthenticationToken(username, null, null);
}
return null;
}
}
How can I resolve this issue?
Lot of problems are there in your code.
(ApplicationContext) authenticationManager()
you can not cast AuthenticationManager to ApplicationContext
.addFilter(new ApplicationContextHeaderFilter(...))
I don't know Why you are using ApplicationContextHeaderFilter for simple demo application.
You should have preferred BasicAuthenticationFilter or even simple default configuration provided for HttpSecurity with .httpBasic()
You should have preferred UsernamePasswordAuthenticationFilter or even simple default configuration provided in HttpSecurity with .formLogin()
CustomAuthenticationProvider extends BasicAuthenticationFilter
An authentication provider is one which implements AuthenticationProvider interface. In your case naming should be xxxAuthFilter.
You have done nothing in below code.(got existing authentication object and set it back without creating an valid authentication object.)
UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
Coming to the AuthenticationManager and AuthFilters implementation point of view,
For add filter you can add any implementation of Spring Security provided filters as given below
.addFilter(AnyFilterImplementationFromThisLink)
(But not all filters are auth filters. Where auth filters will attempt to authenticate with the authenticationManager configured)
For example If you consider UsernamePasswordAuthenticationFilter or BasicAuthenticationFilter
you should take care of setting AuthenticationManager where your auth manager should override authenticate() method and it should return Authentication object(where Authentication object will have auth principal, credentials and granted authorities list)
Or
If you don't want to implement authentication manager...
In simple way in your filters(implementation of OncePerRequestFilter) doFilterInternal() method set the `Authentication` object in `SecurityContext`
List<GrantedAuthority> authorityList = new ArrayList<>();
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
authorityList.add(authority);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, authorityList);
//Note UsernamePasswordAuthenticationToken implements Authentication
SecurityContextHolder.getContext().setAuthentication(authToken);
How any auth filter works is if there is a valid Authentication object then filter chain will continue without attempting authentication otherwise it will attemptAuthentication by overrided attemptAuthentication() method.
But your ApplicationContextHeaderFilter is a implementation of OncePerRequestFilter where it has no attemptAuthentication() and i don't know the order of ApplicationContextHeaderFilter if it's order is after creating security context then you can set the authentication object to security context.
Your error seems to be that the AuthenticationManager is not present as a Spring Bean.
Option 1
Register an AuthenticationManager in Spring Bean. All is provided by Spring for do this directly in your SecurityConfig class by overriding the WebSecurityConfigurerAdapter#authenticationManagerBean method like explain in the documentation of it
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
Option 2
Avoid to register an AuthenticationManager in Spring, but directly your CustomAuthenticationProvider classs.
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public CustomAuthenticationProvider authenticationProvider() throws Exception {
return new CustomAuthenticationProvider(authenticationManager());
}
}
Don't forget to remove the #Component annotation on the CustomAuthenticationProvider class with this method.
I am not sure but shoudn't the CustomAuthenticationProvider implement AuthenticationProvider and AuthenticationManager is just a container for authentication providers and it seems that you dont have any.
Check this site for more info
https://www.baeldung.com/spring-security-authentication-provider
You can try on this, put it in config security file
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
Create a new java class. And Configure like below:
#Configuration
#RequiredArgsConstructor
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
}

Run a Spring Boot oAuth2 application as resource server AND serving web content

I'm using Spring Boot 1.5.13 and with that Spring Security 4.2.6 and Spring Security oAuth2 2.0.15.
I want to find a best practice setup for our Spring Boot applications that serve a mixed set of content: A REST API, and some web pages that provide a convenience "landing page" for developers with some links on it, plus Swagger based API documentation, which is also web content.
I have a configuration that allows me to run the app with proper authorization code flow, hence I can access all web content via Browser and get authenticated by the configured IdP (in my case PingFederate), plus I can make API calls from within the Browser, i.e. directly or with a REST Client, e.g. with RESTClient.
This is my security configuration:
#Slf4j
#Configuration
#EnableWebSecurity
#EnableOAuth2Sso // this annotation must stay here!
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login**", "/webjars/**", "/css/**").permitAll()
.antMatchers("/cfhealth").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/protected", "/api/**").authenticated();
}
#Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
}
and the oAuth2 configuration:
#Configuration
#Slf4j
public class OAuth2Config extends ResourceServerConfigurerAdapter {
#Value("${pingfederate.pk-uri}")
String pingFederatePublicKeyUri;
#Autowired
PingFederateKeyUtils pingFederateKeyUtils;
#Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
String certificate = pingFederateKeyUtils.getKeyFromServer(pingFederatePublicKeyUri);
String publicKey = pingFederateKeyUtils.extractPublicKey(certificate);
converter.setVerifier(pingFederateKeyUtils.createSignatureVerifier(publicKey));
return converter;
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}
But when I want to call a REST API programmatically/outside the Browser with a bearer token in the header, e.g. with curl, the authorization code flow kicks in and redirects to the local login endpoint. What I want is that API calls accept the bearer token for authentication, without creating a session, and that all web content/mvc calls in the Browser establish a session.
curl -i -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8080/authdemo/api/hello
Adding the #EnableResourceServer annotation to the above SecurityConfig class (and adding security.oauth2.resource.filter-order=3 in the application properties file, I can make the curl command work, but then the authorization code flow is broken, I get the following output in the Browser for all URLs in my application:
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
Now is there a way to get this szenario working nicely? If yes, how would that look like? Or is it only supported in later versions of Spring Boot+Security+oAuth2?
The question at Spring Boot with Security OAuth2 - how to use resource server with web login form? is quite similar
I found the solution: It takes multiple HttpSecurity configurations. I found out by reading the great article written by Matt Raible at https://developer.okta.com/blog/2018/02/13/secure-spring-microservices-with-oauth where he introduced me to the notion of requestMatchers(.). This is how I finally implemented it:
#Configuration
#EnableResourceServer
#EnableWebSecurity(debug = true)
#EnableOAuth2Sso
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new RequestHeaderRequestMatcher("Authorization"))
.authorizeRequests().anyRequest().fullyAuthenticated();
}
}
With that I can access the service with a Browser, leading to a authorization code flow. But accessing the API (or actually any part of the service) leads to a validation of the provided Bearer token.
And to illustrate the way how some endpoints can be exluded/made public in such a case, here's how I configure the actuator endpoints and one very simple 'ping' endpoint I've added myself:
#Configuration
#Order(1)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new OrRequestMatcher(EndpointRequest.to("health", "info"),
new AntPathRequestMatcher("/cfhealth"))).authorizeRequests().anyRequest().permitAll();
}
}
And my implementation of the /cfhealth endpoint:
#Controller
#Slf4j
public class MainController {
#GetMapping(value = "/cfhealth")
#ResponseBody
public String cfhealth() {
return "ok";
}
}
I'm happy to learn from others if that's the best practice way of Spring Security configuration or if there are better ways to do it. I've spent quite some time on the topic in the last few weeks on it, and it takes quite some effort to grasp the basic Spring Security concepts.

Spring Security Remember Me Does not work With Spring boot 1.5.2, Spring 4.3, Spring Security 4.2 [duplicate]

Right after registration (sign up) I'm logging in my user programmatically via Spring Security:
public register(HttpServletRequest request, String user, String password) {
...
request.login(user, password);
}
This works fine, but it doesn't create the remember-me cookie (although with interactive login the cookie is created fine).
Now I've read in this and this answer, that you have to wire in the implementation of RememberMeServices (I use PersistentTokenBasedRememberMeServices) and then call onLoginSuccess. I haven't been successful to autowire PersistentTokenBasedRememberMeServices.
How to make this work? Is this the right way? Why Spring Security doesn't offer a more convenient way?
P.S.: This is an excerpt from my configuration:
#Configuration
#EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.tokenRepository(new MyPersistentTokenRepository())
.rememberMeCookieName("rememberme")
.tokenValiditySeconds(60 * 60 * 24)
.alwaysRemember(true)
.useSecureCookie(true)
.and()
....
...
}
}
You didn't mention the Spring version. Below configuration will work with Spring 4 but you can modify it for other version. In your WebSecConf class autowire PersistentTokenRepository and UserDetailsService interfaces. Add Bean to get PersistentTokenBasedRememberMeServices instance.
#Configuration
#EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {
#Autowired
PersistentTokenRepository persistenceTokenRepository;
#Autowired
UserDetailsService userDetailsService;
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.tokenRepository(persistenceTokenRepository)
.rememberMeCookieName("rememberme")
.tokenValiditySeconds(60 * 60 * 24)
.alwaysRemember(true)
.useSecureCookie(true)
.and()
....
...
}
#Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new PersistentTokenBasedRememberMeServices("rememberme", userDetailsService, persistenceTokenRepository);
persistenceTokenBasedservice.setAlwaysRemember(true);
return persistenceTokenBasedservice;
}
}
Now in your Controller or class where you are doing programmatic login, autowire PersistentTokenBasedRememberMeServices and add below code inside the method to invoke loginSuccess method.
#Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
persistentTokenBasedRememberMeServices.loginSuccess(request, response, auth);
}
I've stumbled on this issue and struggled a bit to get everything working correctly, for future reference this is how to set things up.
Define a RememberMeService bean configured to your needs.
Use TokenBasedRememberMeServices if you want a simple hash based token system or PersistentTokenBasedRememberMeServices if you'd rather persist the tokens to database. Both solutions are described in further details here : https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/remember-me.html
Please note that the constructor first argument is not the cookie name but the key used to validate remember-me tokens.
#Configuration
public class SecurityBeans {
#Autowire
PersistentTokenRepository persistenceTokenRepository;
#Autowired
UserDetailsService userDetailsService;
#Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new TokenBasedRememberMeServices("remember-me-key", userDetailsService, persistenceTokenRepository);
persistenceTokenBasedservice.setCookieName("rememberme");
persistenceTokenBasedservice.setTokenValiditySeconds(60 * 60 * 24);
persistenceTokenBasedservice.setAlwaysRemember(true);
persistenceTokenBasedservice.setUseSecureCookie(true);
return persistenceTokenBasedservice;
}
}
You should inject the RememberMeService directly when configuring HttpSecurity. You also have to configure the exact same key as defined in your RememberMeService because the configurer also sets up the RememberMeAuthenticationProvider which checks that the remember-me token key generated by RememberMeService is correct.
#Configuration
#EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {
#Autowired
RememberMeServices rememberMeServices;
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.rememberMeServices(rememberMeServices)
.key("remember-me-key")
.and()
....
...
}
}
And finally you should invoke RememberMeService's loginSuccess in your method doing the programmatic login as described in abaghel's answer.

Understanding Spring Boot's Oauth2 starter

I started off looking at the Oauth2 starter project and minimal configuration.
https://github.com/spring-projects/spring-security-oauth/blob/master/tests/annotation/jdbc/src/main/java/demo/Application.java
All the examples either use in memory configuration or jdbc configuration for storing client roles (e.g ClientDetailsServiceConfigurer) . In my case the details should come in LDAP. So I have two questions.
How do override the default to go to ldap instead of memory or jdbc.
In general , where how do I unravel the Spring Boot thread and read the starter source code and how to change default config ? All I see is a high level annotation.
org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer
This indirection in Spring Boot makes it extremely difficult to follow and scant documentation doesn't help. Or maybe I am missing something?
thanks !!! this has been bugging me for a while.
To implement Oauth2 with LDAP, you may follow this tutorial : https://raymondhlee.wordpress.com/2015/12/05/oauth2-authorization-server-with-spring-security.
You may also take a look a this other question: spring-security-oauth2 2.0.7 refresh token UserDetailsService Configuration - UserDetailsService is required
As for your other question "I want to follow the request and see what components get invoked and when": I suggest you add logging.
(1) Add logging in every method
(2) Set log level for security package in application.properties:
logging.level.org.springframework.security=DEBUG
(3) Add CommonsRequestLoggingFilter:
#Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
LOGGER.info("Creating CommonsRequestLoggingFilter");
CommonsRequestLoggingFilter crlf = new CommonsRequestLoggingFilter();
crlf.setIncludeClientInfo(true);
crlf.setIncludeQueryString(true);
crlf.setIncludePayload(true);
return crlf;
}
(4) Add log level for CommonsRequestLoggingFilter (in application.properties):
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
For the OAuth/LDAP tutorial, here's the notable parts (quoted from https://raymondhlee.wordpress.com/2015/12/05/oauth2-authorization-server-with-spring-security):
Authorization Server Configuration Below is my implementation of the
AuthorizationServerConfigurerAdapter. The database schema for JDBC
client details and token services can be found in here.
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private DataSource dataSource;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new JdbcTokenStore(dataSource)).authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
}
Login Security Configuration Below is the security configuration
handling user authorization.
#Configuration
#Order(Ordered.HIGHEST_PRECEDENCE) // note 1
public class LoginConfig extends WebSecurityConfigurerAdapter {
#Value("${ldap.domain}")
private String DOMAIN;
#Value("${ldap.url}")
private String URL;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
// Only requests matching regex are handled by this security configurer
http.requestMatchers().regexMatchers("/login", "/login.+", "/oauth/.+", "/j_spring_security_check", "/logout"); //
AuthenticationEntryPoint entryPoint = entryPoint();
http.exceptionHandling().authenticationEntryPoint(entryPoint);
http.formLogin(); // note 3i
http.addFilter(usernamePasswordAuthenticationFilter());
http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().antMatchers("/oauth/**").authenticated();
http.authorizeRequests().antMatchers("/j_spring_security_check").anonymous().and().csrf().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception { // note 4
authManagerBuilder.parentAuthenticationManager(authenticationManager());
}
protected AuthenticationManager authenticationManager() {
return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
}
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(DOMAIN, URL);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
private AuthenticationEntryPoint entryPoint() {
return new LoginUrlAuthenticationEntryPoint("/login");
}
private UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() {
UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager();
AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler("/login?login_error=true");
filter.setAuthenticationFailureHandler(failureHandler);
return filter;
}
}

can't get Spring Security to work

I'm new to Spring Security so I probably miss out on something. I have a Spring Application that starts a Jetty with a WebApplication I want to secure using Spring Security. The webapp is running and reachable, but not restricted. I've tried a lot of stuff but nothing worked so I broke it down to a minimal setup, but still no chance.
the webapp is configured by the following java configuration:
#EnableWebMvc
#Configuration
#Import(SecurityConfiguration.class)
#ComponentScan(useDefaultFilters = false, basePackages = { "myapp.web" }, includeFilters = { #ComponentScan.Filter(Controller.class) })
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {
/**
* Allow the default servlet to serve static files from the webapp root.
*/
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
and Spring Security configured here:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("ADMIN")
.authorities("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.hasAuthority("ADMIN");
}
}
and some controller like this:
#Controller
public class SecuredController {
#RequestMapping(value = "/secure", method = RequestMethod.GET)
#ResponseBody
public String secured() {
return "you should not see this unless you provide authentication";
}
}
Everything starts up all right, the log tells me, that the controller is mapped...
[2014-10-01 20:21:29,538, INFO ] [main] mvc.method.annotation.RequestMappingHandlerMapping:197 - Mapped "{[/secure],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String myapp.web.SecuredController.secured()
...and that security is in place as well...
[2014-10-01 20:21:30,298, INFO ] [main] gframework.security.web.DefaultSecurityFilterChain:28 - Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher#1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#352c308, org.springframework.security.web.context.SecurityContextPersistenceFilter#2af616d3, org.springframework.security.web.header.HeaderWriterFilter#1a2e2935, org.springframework.security.web.csrf.CsrfFilter#64f857e7, org.springframework.security.web.authentication.logout.LogoutFilter#bc57b40, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#3deb2326, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#7889a1ac, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#7d373bcf, org.springframework.security.web.session.SessionManagementFilter#5922ae77, org.springframework.security.web.access.ExceptionTranslationFilter#7e1a1da6, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#1051817b]
... but the /secure url of my controller is unconditionally reachable. What am I doing wrong?
ps. I want to avoid xml config
In order to integrate Spring Security with Spring MVC you have to use #EnableWebMvcSecurity annotation instead of #EnableWebSecurity in SecurityConfiguration class.
I figured, I had to move the initialization of the Spring Security configuration to the root context, not the dispatcher-servlet context, and add the following line where i configure the context of my embedded Jetty:
context.addFilter(new FilterHolder(new DelegatingFilterProxy("springSecurityFilterChain")), "/*", EnumSet.allOf(DispatcherType.class));

Resources