0

We are trying to protect our web services using spring oauth2.0. We have created a Demo project which runs fine on below-mentioned spring version:-

spring-security-web, spring-security-config :- 4.1.5.RELEASE spring-security-oauth2 :- 2.2.0.RELEASE spring framework version: 4.2.0.RELEASE

The demo application is protecting our rest services using OAUTH2.0.

But when we start our application while loading context it throws below error.

"[ERROR ] SRVE0321E: The [springSecurityFilterChain] filter did not load during start up. Filter [springSecurityFilterChain]: could not be initialized".

Did some research and all of them point to some XML based configuration? which we would like to avoid as the same code is working on Demo application so it should work on another project as well.

Any help or clue is highly appreciated !!

web.xml

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">


    <!-- The definition of the Root Spring Container shared by all Servlets 
        and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.example.web.listener.ApplicationContextListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
        <url-pattern>/example</url-pattern>  <!-- For my machine only -->
    </servlet-mapping>

    <error-page>
        <error-code>500</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>503</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/error.jsp</location>
    </error-page>
</web-app>

JAVA CLASSES :-

1. SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {


     @SuppressWarnings("deprecation")

     @Bean public static NoOpPasswordEncoder passwordEncoder() { 
         return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance(); }

     @Bean

     @Override public AuthenticationManager authenticationManagerBean() throws
      Exception { return super.authenticationManagerBean(); }


}`


2. ResourceServerConfiguration.java

@Configuration
@EnableResourceServer
public class ResourceServerConfigurations extends
        ResourceServerConfigurerAdapter {

    public static final String RESOURCE_ID = "krsna";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        RemoteTokenServices tokenService = new RemoteTokenServices();
        tokenService.setClientId("resource-client");
        tokenService.setClientSecret("123456");
        tokenService
                .setCheckTokenEndpointUrl("http://localhost:8090/example-web/oauth/check_token");
        resources.resourceId(RESOURCE_ID).tokenServices(tokenService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.httpBasic().disable().requestMatchers().and().authorizeRequests()
                .antMatchers("/**").authenticated().and().exceptionHandling()
                .accessDeniedHandler(new OAuth2AccessDeniedHandler());

    }

}

3. SecurityWebApplicationInitializer.java

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}

4. AuthorizationServerConfiguration.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends
        AuthorizationServerConfigurerAdapter {

    public static final String RESOURCE_ID = "krsna";

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {

        clients.inMemory().withClient("clientapp").secret("123456")
                .authorizedGrantTypes("client_credentials")
                .scopes("read", "write", "trust").resourceIds(RESOURCE_ID)
                .accessTokenValiditySeconds(120).and().withClient("clientcred")
                .secret("123456").authorizedGrantTypes("client_credentials")
                .scopes("read", "write", "trust").resourceIds(RESOURCE_ID)
                .accessTokenValiditySeconds(120).and()
                .withClient("resource-client").secret("123456")
                .authorizedGrantTypes("client_credentials")
                .scopes("read", "write", "trust").resourceIds(RESOURCE_ID)
                .accessTokenValiditySeconds(120);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints.tokenStore(new InMemoryTokenStore()).authenticationManager(
                authenticationManager);

    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer)
            throws Exception {
        oauthServer.checkTokenAccess("permitAll()");
    }

}

SECURITY-CONFIG.XML

<!-- This is default url provided by spring to get the tokens(access and refresh) from OAuth -->
 <http pattern="/oauth/token" create-session="stateless"
  authentication-manager-ref="clientAuthenticationManager"
  xmlns="http://www.springframework.org/schema/security">
  <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
  <anonymous enabled="false" />
  <http-basic entry-point-ref="clientAuthenticationEntryPoint" />

  <!-- include this only if you need to authenticate clients via request
   parameters -->

  <custom-filter ref="clientCredentialsTokenEndpointFilter"
   after="BASIC_AUTH_FILTER" />
  <access-denied-handler ref="oauthAccessDeniedHandler" />
 </http>

 <!-- This is where we tell spring security what URL should be protected
  and what roles have access to them -->

 <http pattern="/users/**" create-session="never"
  entry-point-ref="oauthAuthenticationEntryPoint"
  access-decision-manager-ref="accessDecisionManager"
  xmlns="http://www.springframework.org/schema/security">
  <anonymous enabled="false" />
  <intercept-url pattern="/users/**" access="ROLE_OAUTH_CLIENT" />
  <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
  <access-denied-handler ref="oauthAccessDeniedHandler" />
 </http>


 <bean id="oauthAuthenticationEntryPoint"
  class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
  <property name="realmName" value="sample" />
 </bean>

 <bean id="clientAuthenticationEntryPoint"
  class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
  <property name="realmName" value="sample/oauthClient" />
  <property name="typeName" value="Basic" />
 </bean>

 <bean id="oauthAccessDeniedHandler"
  class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

 <bean id="clientCredentialsTokenEndpointFilter"
  class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
  <property name="authenticationManager" ref="clientAuthenticationManager" />
 </bean>

 <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
  xmlns="http://www.springframework.org/schema/beans">
  <constructor-arg>
   <list>
    <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
    <bean class="org.springframework.security.access.vote.RoleVoter" />
    <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
   </list>
  </constructor-arg>
 </bean>

 <authentication-manager id="clientAuthenticationManager"
  xmlns="http://www.springframework.org/schema/security">
  <authentication-provider user-service-ref="clientDetailsUserService" />
 </authentication-manager>


 <!-- Here we have hard-coded user name and password details. We can replace this with a user defined service to get users
  credentials from DB -->
 <authentication-manager alias="authenticationManager"
  xmlns="http://www.springframework.org/schema/security">
  <authentication-provider>
  <user-service id="userDetailsService">
    <user name="raj" password="raj@1234" authorities="ROLE_OAUTH_CLIENT" />
   </user-service>
  </authentication-provider>
 </authentication-manager>

 <bean id="clientDetailsUserService"
  class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
  <constructor-arg ref="clientDetails" />
 </bean>


 <bean id="tokenStore"
          class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" /> 

 <!-- tokenServices bean for defining token based configurations, token validity etc -->
 <bean id="tokenServices"
  class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
  <property name="tokenStore" ref="tokenStore" />
  <property name="supportRefreshToken" value="true" />
  <property name="accessTokenValiditySeconds" value="120" />
  <property name="clientDetailsService" ref="clientDetails" />
 </bean>

<bean id="requestFactory"
        class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
        <constructor-arg name="clientDetailsService" ref="clientDetails" />
    </bean>

<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
    <property name="tokenStore" ref="tokenStore"/>
    <property name="requestFactory" ref="requestFactory" />
</bean>

 <oauth:authorization-server
  client-details-service-ref="clientDetails"  token-services-ref="tokenServices"
  user-approval-handler-ref="userApprovalHandler">
  <oauth:authorization-code />
  <oauth:implicit />
  <oauth:refresh-token />
  <oauth:client-credentials />
  <oauth:password />
 </oauth:authorization-server>

 <oauth:resource-server id="resourceServerFilter"
  resource-id="sample" token-services-ref="tokenServices" />

 <oauth:client-details-service id="clientDetails">
  <!-- client -->
  <oauth:client client-id="trusted client"
   authorized-grant-types="password,refresh_token,client_credentials"
   authorities="ROLE_OAUTH_CLIENT" scope="read,write." resource-ids="sample" secret="secret" />

  <oauth:client client-id="trusted client with secret"
   authorized-grant-types="password,authorization_code,refresh_token,implicit"
   secret="somesecret" authorities="ROLE_OAUTH_CLIENT" />

 </oauth:client-details-service>

 <sec:global-method-security
  pre-post-annotations="enabled" proxy-target-class="true">

  <sec:expression-handler ref="oauthExpressionHandler" />
 </sec:global-method-security>

 <oauth:expression-handler id="oauthExpressionHandler" />
 <oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
INDRAJITH EKANAYAKE
  • 3,894
  • 11
  • 41
  • 63
Kundan Saini
  • 87
  • 2
  • 6
  • 15
  • It seems like there should be a caused-by of some sort, "could not be initialized" is not so informative. Are you able to share any additional error information from a stack trace, for example? – jzheaux Mar 05 '19 at 23:48
  • Thanks @jzheaux for your kind attention. We found the cause of the issue. As per our application architecture we have one ContextLoaderListener to load all the beans. So SecurityWebApplicationInitializer not able to load throwing above mentioned error. Now we changes the approach to xml based configuration instead of annotation based configuration and placed security-config.xml. This loads the application fine along with security. – Kundan Saini Mar 07 '19 at 14:05
  • Now if we are trying to access any rest services without access token it gives us unauthorized error !! which is expected. But when we generate access token to call rest services the services gives below mentioned error. { error: "invalid_token" error_description: "Invalid access token: f853bcc5-7801-42d3-9cb8-303fc67b0453" } We tried many solutions mentioned at different sources but not able to resolve it. Ref URL :- https://stackoverflow.com/questions/29596036/spring-security-oauth2-resource-server-always-returning-invalid-token – Kundan Saini Mar 07 '19 at 14:09
  • @jzheaux please find SECURITY-CONFIG.XML in edited question. Also we are using InMemoryTokenStore. – Kundan Saini Mar 07 '19 at 14:15

0 Answers0