Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

org.springframework.security.oauth2.provider.endpoint.TokenEndpoint handleException

I'm using "Spring OAuth2 REST" code from http://www.e-zest.net/blog/rest-authentication-using-oauth-2-0-resource-owner-password-flow-protocol/#comment-5993 and developing to work with the latest version of Spring-Security-OAuth2 (which is v 2.0.7.RELEASE), but note that original code is works only for latest lower versions (which is 1.0.5.RELEASE) and not for latest. To use latest version's of dependencies I've modified below two files, remaining code from mentioned site / URL using as it is.

I'm using the following configuration:

<?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:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
    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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">


    <http pattern="/oauth/token" create-session="stateless"  authentication-manager-ref="authenticationManager"
        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="/resources/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/resources/**" method="GET" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>

    <http pattern="/logout" create-session="never" 
        entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/logout" method="GET" />
        <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"   />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>

    <bean id="logoutSuccessHandler" class="demo.oauth2.authentication.security.LogoutImpl" >
        <property name="tokenstore" ref="tokenStore"></property>
    </bean>

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

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

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

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

    <bean id="clientDetails" class="demo.oauth2.authentication.security.ClientDetailsServiceImpl"/>

    <authentication-manager id="userAuthenticationManager" 
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider  ref="customUserAuthenticationProvider">
        </authentication-provider>
    </authentication-manager>

    <bean id="customUserAuthenticationProvider"
        class="demo.oauth2.authentication.security.CustomUserAuthenticationProvider">
    </bean>

    <oauth:authorization-server
        client-details-service-ref="clientDetails" token-services-ref="tokenServices">
        <oauth:authorization-code />
        <oauth:implicit/>
        <oauth:refresh-token/>
        <oauth:client-credentials />
        <oauth:password authentication-manager-ref="userAuthenticationManager"/>
    </oauth:authorization-server>

    <oauth:resource-server id="resourceServerFilter"
        resource-id="springsec" token-services-ref="tokenServices" />       
    <bean id="tokenStore"              class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />


    <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="300000"></property>
        <property name="clientDetailsService" ref="clientDetails" />
    </bean>


    <mvc:annotation-driven />   
    <mvc:default-servlet-handler />

    <bean id="MyResource" class="demo.oauth2.authentication.resources.MyResource"></bean>

</beans>

and

package demo.oauth2.authentication.security;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;

@Service
public class ClientDetailsServiceImpl implements ClientDetailsService {

    private static final String CLIENT_CREDENTIALS = "client_credentials";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String PASSWORD = "password";

@Override
public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
    List<String> authorizedGrantTypes = new ArrayList<>();
    authorizedGrantTypes.add(PASSWORD);
    authorizedGrantTypes.add(REFRESH_TOKEN);
    authorizedGrantTypes.add(CLIENT_CREDENTIALS);

    if (clientId.equals("client1")) {
        BaseClientDetails clientDetails = new BaseClientDetails();
        clientDetails.setClientId("client1");
        clientDetails.setClientSecret("client1");
        clientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
        return clientDetails;
    } 
    else if(clientId.equals("client2")){
        BaseClientDetails clientDetails = new BaseClientDetails();
        clientDetails.setClientId("client2");
        clientDetails.setClientSecret("client2");
        clientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
        return clientDetails;
    }
    else{
        throw new NoSuchClientException("No client with requested id: " + clientId);
    }
}

The code is giving error at above class. Also when I tried to execute following command from POSTMAN Rest Client http://localhost:8080/demo.rest.springsecurity.oauth2.0.authentication/oauth/token?username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password

it give me the following errors. The main error on console:

Mar 26, 2015 4:57:40 PM org.springframework.security.oauth2.provider.endpoint.TokenEndpoint handleException
INFO: Handling error: InvalidScopeException, Empty scope (either the client or the user is not allowed the requested scopes)

This is the message from Postman Rest Client:

{
    "error": "invalid_scope",
    "error_description": "Empty scope (either the client or the user is not allowed the requested scopes)"
}
like image 736
PAA Avatar asked Mar 25 '15 22:03

PAA


Video Answer


1 Answers

I got the solution to this problem. You need to specify the value for the scope like read,write,trust. For Ex: http://localhost:8080/demo.rest.springsecurity.oauth2.0.authentication/oauth/token?username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password&scope=read,write,trust enter image description here

Here is what I can access protected resources as well by providing access token http://localhost:8080/demo.rest.springsecurity.oauth2.0.authentication/resources/MyResource/getMyInfo?access_token=27e28c65-5b18-4a0f-b55b-cfs2c5f6997b

enter image description here

This is really working very nice !!

like image 126
PAA Avatar answered Oct 19 '22 22:10

PAA