2

I am working on an application guarding few REST APIs with Spring Security OAuth2, now the requirement is to wrap Spring OAuth2 exceptions and customize it in JSON format. Below is my existing spring security configurations, I have already tried answer mentioned on this link without success how do I wrap an oauth2 exception

This is default url to get a token from OAuth

<http pattern="/oauth/token" create-session="never"
      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"
                   after="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

This will guard the following apis mentioned below

<http pattern="/api/**" 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="/api/api/hospital/**" access="IS_AUTHENTICATED_FULLY" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

This is used to generate the key

<bean id="authenticationKeyGenerator" class="com.moss.oauth.MossAuthenticationKeyGenerator"/>

--

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

--

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="framework/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="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>

--

<!-- This is simple authentication manager implementation using hibernate, gets users
    credentials from DB -->

<bean id="userDetailsService" class="com.moss.service.impl.UserServiceImpl"></bean>

<!-- Same password encoder must be used for storing the password and user authenticationManager  -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

--

<authentication-manager alias="authenticationManager"
                        xmlns="http://www.springframework.org/schema/security">
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder ref="passwordEncoder"/>
    </authentication-provider>
</authentication-manager>

--

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

--

<bean id="tokenStore" class="com.moss.oauth.MossHibernateTokenStore">
    <constructor-arg ref="authenticationKeyGenerator" />
</bean>

--

<bean id="tokenServices"
    class="com.moss.oauth.MossResourceAndAuthenticationTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="${oauth.refresh.token.support}" />
    <property name="accessTokenValiditySeconds" value="${oauth.access.token.validity}" />
    <property name="clientDetailsService" ref="clientDetails" />
    <property name="userDetailsService" ref="userDetailsService" />
</bean>

--

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

--

<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="framework" token-services-ref="tokenServices" />

<bean id="clientDetails" class="com.moss.oauth.MossHibernateClientDetailsService">
    <constructor-arg ref="dataSource" />
</bean>

--

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

--

Community
  • 1
  • 1
Soumyaansh
  • 8,626
  • 7
  • 45
  • 45

1 Answers1

0

A custom response will be a point in code where you can access the default response and you can send a POJO instead of it, for example if you want to change error_description to error_info or anything else, or you may want to add more variables to the response. The solution does exist, but I think it is painful to implement to say the least, as I copy it from here:

This problem has been solved. Follow the workaround below: 1 extend OAuth2Exception to a new class, such as CustomOAuth2Exception. In the custom class, add some specific properties. 2 custom DefaultWebResponseExceptionTranslator and register the custom translator in AuthorizationServerConfiguration. 3 custom two jackson serializers annotated in OAuth2Exception and annotated your CustomOAuth2Exception with the two custom serializers. 4 use ObjectMapper to override initial serializers with custom serializers.

Hasson
  • 1,894
  • 1
  • 21
  • 25