Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java + spring security oauth token not returned with 404 page not found

Everyone, I am aware that there is already a solution for similar kind of issue but this question is different.

I also read the link present, but the solution didn't apply to me.

My Question is that I am trying to secure my Java+Spring+Jersey webservice application using oauth2.0 and have been using spring-security-oauth2 library version.

Whenever I make a call to the /oauth/token the application verifies the details provided under the header( client_secret, client_id and grant_type), the client is successfully authenticated but token data is not returned from the server rather a 404 page not found response is shown.

here is the below configurations:

  1. web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring/dispatcher-servlet.xml</param-value>
        </context-param>
    
        <servlet>
            <servlet-name>jersey-servlet</servlet-name>
            <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>com.tprivity.babycenter.ws</param-value>
            </init-param>
            <init-param>
                <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
                <param-value>true</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>jersey-servlet</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    
        <filter>
            <filter-name>springSecurityFilterChain</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    </web-app>
    
  2. dispatcher-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
        xmlns:p="http://www.springframework.org/schema/p" xmlns:security="http://www.springframework.org/schema/security"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
            http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
    
        <security:http pattern="/oauth/token" create-session="stateless"
            authentication-manager-ref="authenticationManager">
            <security:intercept-url pattern="/oauth/token"
                access="IS_AUTHENTICATED_FULLY" />
            <security:anonymous enabled="false" />
            <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
            <security:custom-filter ref="clientCredentialsTokenEndpointFilter"
                before="BASIC_AUTH_FILTER" />
            <security:access-denied-handler ref="oauthAccessDeniedHandler" />
        </security:http>
    
        <security:http pattern="/ws/**" create-session="never"
            authentication-manager-ref="authenticationManager" entry-point-ref="oauthAuthenticationEntryPoint">
            <security:anonymous enabled="false" />
            <security:intercept-url pattern="/ws/**"
                method="GET" access="IS_AUTHENTICATED_FULLY" />
            <security:intercept-url pattern="/ws/**"
                method="POST" access="IS_AUTHENTICATED_FULLY" />
            <security:custom-filter ref="resourceServerFilter"
                before="PRE_AUTH_FILTER" />
            <security:access-denied-handler ref="oauthAccessDeniedHandler" />
        </security:http>
    
        <bean id="oauthAuthenticationEntryPoint"
            class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        </bean>
    
        <bean id="clientAuthenticationEntryPoint"
            class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
            <property name="realmName" value="springsec/client" />
            <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="authenticationManager" />
        </bean>
    
        <security:authentication-manager alias="authenticationManager">
            <security:authentication-provider
                user-service-ref="clientDetailsUserService" />
        </security:authentication-manager>
    
        <bean id="clientDetailsUserService"
            class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
            <constructor-arg ref="clientDetails" />
        </bean>
    
        <bean id="clientDetails"
            class="org.springframework.security.oauth2.provider.client.JdbcClientDetailsService">
            <constructor-arg index="0">
                <ref bean="dataSource" />
            </constructor-arg>
        </bean>
    
        <security:authentication-manager id="userAuthenticationManager">
            <security:authentication-provider
                ref="customUserAuthenticationProvider" />
        </security:authentication-manager>
    
        <bean id="customUserAuthenticationProvider"
            class="com.tprivity.babycenter.ws.security.CustomUserAuthenticationProvider">
        </bean>
    
        <!-- Authorization Server Configuration of the server is used to provide 
            implementations of the client details service and token services and to enable 
            or disable certain aspects of the mechanism globally. -->
        <oauth2:authorization-server
            client-details-service-ref="clientDetails" token-services-ref="tokenServices"
            user-approval-handler-ref="userApprovalHandler">
            <oauth2:authorization-code />
            <oauth2:implicit />
            <oauth2:refresh-token />
            <oauth2:client-credentials />
            <oauth2:password authentication-manager-ref="userAuthenticationManager" />
        </oauth2:authorization-server>
    
        <oauth2:resource-server id="resourceServerFilter"
            resource-id="springsec" token-services-ref="tokenServices" />
    
        <bean id="tokenStore"
            class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
            <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
        </bean>
    
        <!-- Configure Authentication manager -->
        <bean id="passwordEncoder"
            class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
            <constructor-arg name="strength" value="11" />
        </bean>
    
        <!-- Grants access if only grant (or abstain) votes were received. We can 
            protect REST resource methods with JSR-250 annotations such as @RolesAllowed -->
        <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
            <property name="decisionVoters">
                <list>
                    <bean class="org.springframework.security.access.annotation.Jsr250Voter" />
                </list>
            </property>
        </bean>
    
        <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>
            <property name="clientDetailsService" ref="clientDetails" />
        </bean>
    
        <!-- A user approval handler that remembers approval decisions by consulting 
            existing tokens -->
        <bean id="oAuth2RequestFactory"
            class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
            <constructor-arg ref="clientDetails" />
        </bean>
    
        <bean id="userApprovalHandler"
            class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
            <property name="requestFactory" ref="oAuth2RequestFactory" />
            <property name="tokenStore" ref="tokenStore" />
        </bean>
    </beans>
    

below is the logs for the same.

DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - <Checking match of request : '/oauth/token'; against '/oauth/token'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 1 of 7 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 2 of 7 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 3 of 7 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 4 of 7 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'>
DEBUG [org.springframework.security.web.authentication.www.BasicAuthenticationFilter] - <Basic Authentication Authorization header found for user 'bccws'>
DEBUG [org.springframework.security.authentication.ProviderManager] - <Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider>
WARN [org.springframework.context.support.ResourceBundleMessageSource] - <ResourceBundle [messages] not found for MessageSource: Can't find bundle for base name messages, locale en_US>
WARN [org.springframework.context.support.ResourceBundleMessageSource] - <ResourceBundle [labels] not found for MessageSource: Can't find bundle for base name labels, locale en_US>
WARN [org.springframework.context.support.ResourceBundleMessageSource] - <ResourceBundle [errors] not found for MessageSource: Can't find bundle for base name errors, locale en_US>
DEBUG [org.springframework.jdbc.core.JdbcTemplate] - <Executing prepared SQL query>
DEBUG [org.springframework.jdbc.core.JdbcTemplate] - <Executing prepared SQL statement [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]>
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - <Fetching JDBC Connection from DataSource>
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - <Returning JDBC Connection to DataSource>
DEBUG [org.springframework.security.web.authentication.www.BasicAuthenticationFilter] - <Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f9d8c511: Principal: org.springframework.security.core.userdetails.User@593829e: Username: bccws; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ADMIN>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 5 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'>
DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - <Checking match of request : '/oauth/token'; against '/oauth/token'>
DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] - <Secure object: FilterInvocation: URL: /oauth/token; Attributes: [IS_AUTHENTICATED_FULLY]>
DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] - <Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f9d8c511: Principal: org.springframework.security.core.userdetails.User@593829e: Username: bccws; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ADMIN>
DEBUG [org.springframework.security.access.vote.AffirmativeBased] - <Voter: org.springframework.security.access.vote.RoleVoter@6dbd30e2, returned: 0>
DEBUG [org.springframework.security.access.vote.AffirmativeBased] - <Voter: org.springframework.security.access.vote.AuthenticatedVoter@19d7bbb3, returned: 1>
DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] - <Authorization successful>
DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] - <RunAsManager did not change Authentication object>
DEBUG [org.springframework.security.web.FilterChainProxy] - </oauth/token reached end of additional filter chain; proceeding with original chain>
DEBUG [org.springframework.security.web.access.ExceptionTranslationFilter] - <Chain processed normally>
DEBUG [org.springframework.security.web.context.SecurityContextPersistenceFilter] - <SecurityContextHolder now cleared, as request processing completed>

I have still been looking at the problem but not heading to any solution. Any help would be appreciated.

like image 595
Vivek Singh Avatar asked Oct 30 '15 08:10

Vivek Singh


People also ask

What is OAuth 2.0 and how it works in spring boot?

OAuth2 is an authorization framework that enables the application Web Security to access the resources from the client. To build an OAuth2 application, we need to focus on the Grant Type (Authorization code), Client ID and Client secret.

What is OAuth 2.0 in Spring Security?

OAuth 2.0 was developed by IETF OAuth Working Group and published in October of 2012. It serves as an open authorization protocol for enabling a third party application to get limited access to an HTTP service on behalf of the resource owner.


1 Answers

This happens when your security filter does not have oauth/token endpoint in its context. Try adding context attribute in web.xml while registering the springSecurityFilterChain

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
    <param-name>contextAttribute</param-name>
    <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher</param-value>
</init-param>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>

like image 130
Imrank Avatar answered Nov 15 '22 00:11

Imrank