1
votes

I have written a simple spring web service which works fine until I try to enable web security for user authentication.

I have set all spring configurations for the project programmatically (first time I've tried this approach), I am using spring boot for booting up the web service (also first time I've tried spring boot), and for this, I am using the following spring APIs (spring-boot-starter-ws:1.1+ and spring-security-xxx:3.+).

The Web Service endpoint is defined as follows:

@Endpoint
public class AWebServiceEndpoint extends WsConfigurerAdapter {

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "aRequest")
    @ResponsePayload
    public AResponse request(@RequestPayload ARequest request) {
         ...

The Web Service configuration is defined as follows:

@Configuration
@EnableWs
@ComponentScan
public class WebServiceConfig extends WsConfigurerAdapter {

    @Bean
    public ServletRegistrationBean dispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);

        return new ServletRegistrationBean(servlet, "/ws/A/Service");
    }

    ....

The Web Securityconfiguration is defined as follows:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests().antMatchers("/**").hasRole("alogin").and().httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication()
            .withUser("testuser").password("password").roles("alogin");
    }
}

When I call the Web Service with Web Security configured, I get the following spring debug stacktrace:

04-Jul-2014 12:21:07,084 [DEBUG] HttpServletBean - Initializing servlet 'messageDispatcherServlet' 04-Jul-2014 12:21:07,085 [DEBUG] MutablePropertySources - Adding [servletConfigInitParams] PropertySource with lowest search precedence 04-Jul-2014 12:21:07,085 [DEBUG] MutablePropertySources - Adding [servletContextInitParams] PropertySource with lowest search precedence 04-Jul-2014 12:21:07,085 [DEBUG] MutablePropertySources - Adding [jndiProperties] PropertySource with lowest search precedence 04-Jul-2014 12:21:07,085 [DEBUG] MutablePropertySources - Adding [systemProperties] PropertySource with lowest search precedence 04-Jul-2014 12:21:07,085 [DEBUG] MutablePropertySources - Adding [systemEnvironment] PropertySource with lowest search precedence 04-Jul-2014 12:21:07,085 [DEBUG] AbstractEnvironment - Initialized StandardServletEnvironment with PropertySources [servletConfigInitParams,servletContextInitParams,jndiProperties,systemProperties,systemEnvironment] 04-Jul-2014 12:21:07,086 [INFO ] FrameworkServlet - FrameworkServlet 'messageDispatcherServlet': initialization started 04-Jul-2014 12:21:07,087 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'messageFactory' 04-Jul-2014 12:21:07,093 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'defaultMethodEndpointAdapter' 04-Jul-2014 12:21:07,093 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'soapFaultAnnotationExceptionResolver' 04-Jul-2014 12:21:07,093 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'simpleSoapExceptionResolver' 04-Jul-2014 12:21:07,093 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'payloadRootAnnotationMethodEndpointMapping' 04-Jul-2014 12:21:07,093 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'soapActionAnnotationMethodEndpointMapping' 04-Jul-2014 12:21:07,094 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'annotationActionEndpointMapping' 04-Jul-2014 12:21:07,094 [DEBUG] MessageDispatcherServlet - No MessageDispatcher found in servlet 'messageDispatcherServlet': using default 04-Jul-2014 12:21:07,094 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'request' 04-Jul-2014 12:21:07,094 [DEBUG] MessageDispatcherServlet - Published [org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition@7ec50147] as request.wsdl 04-Jul-2014 12:21:07,095 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'requestSchema' 04-Jul-2014 12:21:07,095 [DEBUG] MessageDispatcherServlet - Published [SimpleXsdSchema{http://www.destin8.co.uk/Chief}] as requestSchema.xsd 04-Jul-2014 12:21:07,095 [DEBUG] FrameworkServlet - Published WebApplicationContext of servlet 'messageDispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.messageDispatcherServlet] 04-Jul-2014 12:21:07,095 [INFO ] FrameworkServlet - FrameworkServlet 'messageDispatcherServlet': initialization completed in 9 ms 04-Jul-2014 12:21:07,095 [DEBUG] HttpServletBean - Servlet 'messageDispatcherServlet' configured successfully 04-Jul-2014 12:21:07,102 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 04-Jul-2014 12:21:07,105 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 04-Jul-2014 12:21:07,106 [DEBUG] HttpSessionSecurityContextRepository - No HttpSession currently exists 04-Jul-2014 12:21:07,106 [DEBUG] HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created. 04-Jul-2014 12:21:07,108 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter' 04-Jul-2014 12:21:07,108 [DEBUG] HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2d5260f3 04-Jul-2014 12:21:07,108 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter' 04-Jul-2014 12:21:07,108 [DEBUG] AntPathRequestMatcher - Checking match of request : '/ws/a/service'; against '/logout' 04-Jul-2014 12:21:07,108 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter' 04-Jul-2014 12:21:07,109 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 04-Jul-2014 12:21:07,109 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 04-Jul-2014 12:21:07,110 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 04-Jul-2014 12:21:07,111 [DEBUG] AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 04-Jul-2014 12:21:07,111 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter' 04-Jul-2014 12:21:07,111 [DEBUG] SessionManagementFilter - Requested session ID A90A65C310CD0D87A9588F386BC51071 is invalid. 04-Jul-2014 12:21:07,111 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 04-Jul-2014 12:21:07,112 [DEBUG] FilterChainProxy$VirtualFilterChain - /ws/A/Service at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 04-Jul-2014 12:21:07,112 [DEBUG] AntPathRequestMatcher - Request '/ws/a/service' matched by universal pattern '/**' 04-Jul-2014 12:21:07,112 [DEBUG] AbstractSecurityInterceptor - Secure object: FilterInvocation: URL: /ws/A/Service; Attributes: [hasRole('ROLE_alogin')] 04-Jul-2014 12:21:07,113 [DEBUG] AbstractSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 04-Jul-2014 12:21:07,115 [DEBUG] AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@1bfa3f4c, returned: -1 04-Jul-2014 12:21:07,116 [DEBUG] AbstractBeanFactory - Returning cached instance of singleton bean 'org.springframework.integration.internalMessagingAnnotationPostProcessor' 04-Jul-2014 12:21:07,117 [DEBUG] ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) ~[spring-security-core-3.2.4.RELEASE.jar:3.2.4.RELEASE]

When I call the web service I am definitely setting authorisation username and password.

Are there any other configuration options I need to set to get web security enabled and working?

Thanks in advance, PM.

1
I can see the BasicAuthenticationFilter firing. How did you authenticate your request? - Dave Syer
I am using Soap UI for firing the request where I set Username and Password values under 'Authentication and Security-related Settings' tab. - Going Bananas
I can't really help with Soap UI, but if seems the problem is there. Maybe it's not using Basic auth? Maybe that's a setting? You can take control with curl and provide the credentials on the command line. - Dave Syer
Tried it with curl as you suggested, and then the request got authenticated against the user okay, so thanks!. So it seems to be Soap UI that is sending in the request differently? Strange, because I use Soap UI with other secured web services and usually authentication works fine! (Soap UI v4.5.0 by the way). Thanks again anyway! - Going Bananas
Got it working with Soap UI now. In Soap UI, I needed to also tick 'Authenticate preemptively' box in Soap UI's Preferences (under HTTP Settings tab). @Dave Syer, if you post your answer as an actual Answer to the Question, then I can accept it so it gets marked as answered. Thanks again, PM. - Going Bananas

1 Answers

2
votes

I can't really help with Soap UI, but it seems the problem is there. Maybe it's not using Basic auth? Maybe that's a setting? You can take control with curl and provide the credentials on the command line.