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)"
}
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
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
This is really working very nice !!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With