Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security oauth2, why does my auth/token authenticates CLIENT but returns 404?

EDIT

I've removed the incorrect configuration which I had posted here because I feel there is already enough incorrect/incomplete configurations out there. After a couple of days struggling It got everything working the way I wanted to so I posted it here as an answer.

like image 989
Hendrik Avatar asked Feb 17 '23 04:02

Hendrik


1 Answers

After a few days of struggling I ended up with a working configuration. Since there is a shortage of good working example on the internet, I will share mine here

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
http://www.springframework.org/schema/security/oauth2    
http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security     
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans         
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jee 
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">

<!-- <sec:debug /> -->

<!-- Used by the token store -->
<bean id="mysqlDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>


<!-- Server configuration -->
<oauth:authorization-server
    client-details-service-ref="clientDetailsService" 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>

<bean id="loggerListener"
    class="org.springframework.security.authentication.event.LoggerListener" />



<!-- Services for clients -->
<sec:authentication-manager id="clientAuthenticationManager">
    <sec:authentication-provider
        user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>

<oauth:client-details-service id="clientDetailsService">
    <oauth:client client-id="client1"
        authorized-grant-types="client_credentials,password,implicit"
        authorities="ROLE_WRITE" secret="secret" />
</oauth:client-details-service>

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

<!-- service for resolving our users. -->
<authentication-manager alias="authenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <authentication-provider user-service-ref="userService" />
</authentication-manager>
<bean id="userService" class="our.UserServiceImpl" />




<!-- Managing Tokens -->
<bean id="tokenServices"
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="true" />
    <property name="clientDetailsService" ref="clientDetailsService" />
    <property name="accessTokenValiditySeconds" value="${security.token.validitySeconds:43200}" />
</bean>
<bean id="tokenStore"
    class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">
    <constructor-arg ref="mysqlDataSource" />
</bean>


<!-- Token Approval Handler -->
<bean id="userApprovalHandler"
    class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
    <property name="tokenServices" ref="tokenServices" />
</bean>

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

<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" />
    <custom-filter ref="clientCredentialsTokenEndpointFilter"
        before="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<http pattern="/oauth/authorize/**" access-denied-page="/login.jsp?authorization_error=true"
    disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/authorize/**" access="IS_AUTHENTICATED_FULLY" />
    <form-login authentication-failure-url="/login.jsp?authentication_error=true"
        default-target-url="http://www.ourwebsite.com/" login-page="/login.jsp"
        login-processing-url="/login.do" />
    <http-basic />
    <anonymous />
</http>


<http pattern="/login**" access-denied-page="/login.jsp?authorization_error=true"
    disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/login**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <form-login authentication-failure-url="/login.jsp?authentication_error=true"
        default-target-url="http://www.outwebsite.com" login-page="/login.jsp"
        login-processing-url="/login.do" />
    <http-basic />
</http>



<http pattern="/**" create-session="stateless"
    entry-point-ref="clientAuthenticationEntryPoint" xmlns="http://www.springframework.org/schema/security"
    access-decision-manager-ref="accessDecisionManager">
    <intercept-url pattern="/**" access="ROLE_WRITE" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>



<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>

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

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

My web.xml looks like this:

<web-app id="Recipe_REST_API" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Our REST API</display-name>

    <!-- Servlets -->
    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

    <!-- filters -->
    <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <servlet-name>mvc-dispatcher</servlet-name>
    </filter-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>



    <!-- listeners -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>
like image 190
Hendrik Avatar answered Apr 29 '23 11:04

Hendrik