Giter Club home page Giter Club logo

spring-rest-service-oauth's Introduction

Spring REST Service OAuth

Build Status

This is a simple REST service that provides a single RESTful endpoint protected by OAuth 2. The REST service is based on the Building a RESTful Web Service getting started guide. This project incorporates the new Java-based configuration support, now available in Spring Security OAuth 2.0. Please log any issues or feature requests to the Spring Security OAuth project.

Spring Projects

The following Spring projects are used in this sample app:

Build and Run

Use Gradle:

./gradlew clean build bootRun

Or Maven:

mvn clean package spring-boot:run

Usage

Test the greeting endpoint:

curl http://localhost:8080/greeting

You receive the following JSON response, which indicates you are not authorized to access the resource:

{
  "error": "unauthorized",
  "error_description": "An Authentication object was not found in the SecurityContext"
}

In order to access the protected resource, you must first request an access token via the OAuth handshake. Request OAuth authorization:

curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"

A successful authorization results in the following JSON response:

{
  "access_token": "ff16372e-38a7-4e29-88c2-1fb92897f558",
  "token_type": "bearer",
  "refresh_token": "f554d386-0b0a-461b-bdb2-292831cecd57",
  "expires_in": 43199,
  "scope": "read write"
}

Use the access_token returned in the previous request to make the authorized request to the protected endpoint:

curl http://localhost:8080/greeting -H "Authorization: Bearer ff16372e-38a7-4e29-88c2-1fb92897f558"

If the request is successful, you will see the following JSON response:

{
  "id": 1,
  "content": "Hello, Roy!"
}

After the specified time period, the access_token will expire. Use the refresh_token that was returned in the original OAuth authorization to retrieve a new access_token:

curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "grant_type=refresh_token&refresh_token=f554d386-0b0a-461b-bdb2-292831cecd57&client_secret=123456&client_id=clientapp"

SSL

To configure the project to run on HTTPS as shown in Building REST services with Spring, enable the https profile. You can do this by uncommenting the appropriate line in the application.properties file of this project. This will change the server port to 8443. Modify the previous requests as in the following command.

curl -X POST -k -vu clientapp:123456 https://localhost:8443/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"

The -k parameter is necessary to allow connections to SSL sites without valid certificates or the self signed certificate which is created for this project.

Cloud Foundry Demo

The service is deployed to Pivotal Cloud Foundry and available for testing. Modify the previous commands to point to the following URL:

curl http://rclarkson-restoauth.cfapps.io/greeting

spring-rest-service-oauth's People

Contributors

mariubog avatar pelli23 avatar raedbh avatar royclarkson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-rest-service-oauth's Issues

403 Forbidden on /oauth/check_token

after acquiring a token from /oauth/token, I want to check if the token is valid or not by calling /oauth/check_token path

curl -X POST -H "Authorization: Basic Y2xpZW50YXBwOjEyMzQ1Ng==" -H "Cache-Control: no-cache" -H "Postman-Token: ca8f304d-06d0-daaa-72eb-df224c3993e1" 'http://localhost:8080/oauth/check_token?token=b4db8484-3ff6-46ca-b8a7-417830042b79'

tried with GET also and got the same error response:

{
  "timestamp": 1437301882689,
  "status": 403,
  "error": "Forbidden",
  "message": "Access is denied",
  "path": "/oauth/check_token"
}

spring configures the mapping

2015-07-19 13:32:44.731  INFO 11989 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/check_token],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.Map<java.lang.String, ?> org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(java.lang.String)

how I can check the token validity?

How to make this project scalable?

Since this project uses clients.inMemory(), it stores all access tokens in a single machine's memory, which makes it impossible to run multiple servers behind a load balancer.

To make this project scalable, I come up with three ideas for now:

  1. Use clients.jdbc() and store tokens into database
  2. Store tokens in Redis.
  3. Use JwtTokenStore. Since JWT is a kind of self-contained token, it is stateless and should be scalable.

As to 2 and 3, I don't know how to do it exactly.

Any ideas?

Extend Oauth2 Example

Hello out there,

currently I do my first steps with Spring Security. I started with the Oauth2 example project.
But I reached a point where one Oauth2Resource has to talk to another Resource.

I read a lot and tried even more, but I dont get it..
So would it possible to extend the example with another resource which just calls the exisiting resource with an Oauth2RestTemplate?

That would be awesome, thanks

separate AuthorizationServer from ResourceServer(single sign-on)

Could you pleae show an example where AuthorizationServer is separeted from ResourceServer.
For example I have two different web applications with REST API on different hosts and ports. I'd like to implement something like SSO(single sign-on) like a third application with a oauth2 over https protocol.

The main question is how to link my existing web applications with the new oauth2 server ? What should be implemented on AuthorizationServer side and what should be implemented in the exisiting web applications in order to use SSO for these existing REST api.

401 Response after calling "/"

OAuth2ServerConfiguration.java

@Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated();
            // @formatter:on
        }

Even thought, "/" url is allowed to anyone, 401 status code is responded at browser while your test case is green.

Thanks.

Facebook/twitter login?

Thanks for the sample code, really helpful! Is it possible to extend the example to provide facebook and twitter login? Or do you have to use something different if you want to do this?

Oauth key annotations are not activated in spring MVC application

Hey every one.
I made a Spring MVC version not a boot of this master project, but it seems that spring context does not activate OAuth annotations like @EnableAuthorizationServer and @EnableResourceServer.
I have to make a spring mvc version not spring boot.
Any suggestion will be appreciated, because i can't do anything, i've been searching and searching but with no results.

this is my web.xml

        <context:annotation-config base-package="net.s2m.ma"></context:annotation-config>
        <context:component-scan base-package="net.s2m.ma" />
        <jpa:repositories base-package="net.s2m.ma"></jpa:repositories>

        <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/test20"></property>
            <property name="username" value="root"></property>
            <property name="password" value=""></property>
        </bean>
        <bean id="persistenceUnitManager"
            class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
            <property name="persistenceXmlLocations">
                <list>
                    <value>classpath*:META-INF/persistence.xml</value>
                </list>
            </property>
            <property name="defaultDataSource" ref="dataSource"></property>
        </bean>
        <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
            <property name="persistenceUnitName" value="MY_P"></property>
        </bean>
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"></property>
        </bean>

and this is my oauth class

    @Configuration
    @Component
    public class OAuth2ServerConfiguration {

        private static final String RESOURCE_ID = "restservice";

        @Configuration
        @Component
        @EnableResourceServer
        @Order(3)
        protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) {
                resources.resourceId(RESOURCE_ID);
            }

            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests().antMatchers("/users").hasRole("ADMIN").antMatchers("/greeting").authenticated();
            }
        }

        @Configuration
        @Component
        @EnableAuthorizationServer
        protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
            private TokenStore tokenStore = new InMemoryTokenStore();

            @Autowired
            @Qualifier("authenticationManagerBean")
            private AuthenticationManager authenticationManager;

            @Autowired
            private CustomUserDetailsService userDetailsService;

            static {
                System.out.println("Hiiiiiiiiiiiiiiiiiiiiiii44444444444");
            }

            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints.tokenStore(this.tokenStore).authenticationManager(this.authenticationManager)
                        .userDetailsService(userDetailsService);
            }

            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                clients.inMemory().withClient("clientapp").authorizedGrantTypes("password", "refresh_token")
                        .authorities("USER").scopes("read", "write").resourceIds(RESOURCE_ID).secret("123456");
            }

            @Bean
            @Primary
            public DefaultTokenServices tokenServices() {
                DefaultTokenServices tokenServices = new DefaultTokenServices();
                tokenServices.setSupportRefreshToken(true);
                tokenServices.setTokenStore(this.tokenStore);
                return tokenServices;
            }
        }

Connect This Project To Mysql

Hello my friends how can connect this project to Mysql database and create tables and read and write to that tables.

Question

I'm using two sources as guides to build an OAuth2 Authorization Server and a Resource Server. Your tutorial is one of them, and the other one is this tutorial.

I'd like to use a simple /oauth/authorize page like in the tutorial. But when I hit that URL over GET, I'm redirected with a 302 to /login, and if I try over POST, I get an error regarding the CSRF token.

What am I doing wrong here?

How to force Spring Security OAuth 2 to use JSON instead of XML?

I've created Spring MVC application and set up Spring Security OAuth 2. While calling methods from my brower I get XML:

<oauth>
    <error_description>
        Full authentication is required to access this resource
    </error_description>
    <error>unauthorized</error>
</oauth>

Instead of JSON:

{
  "error": "unauthorized",
  "error_description": "An Authentication object was not found in the SecurityContext"
}

Browser sends following header:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

When I set json accept header I get JSON. I need to force my authorization server always send JSON. Haven't found any solution. Thanks.

Change InMemoryTokenStore to JdbcTokenStore

I just change InMemoryTokenStore to JdbcTokenStore and use JdbcClientDetailsService.
It was work when curl grant_type with password.
But it failed when reflesh token.
{
"error" : "unauthorized",
"error_description" : "User null does not exist!"
}
I found some message in Spring docs.
"userDetailsService: if you inject a UserDetailsService or if one is configured globally anyway (e.g. in a GlobalAuthenticationManagerConfigurer) then a refresh token grant will contain a check on the user details, to ensure that the account is still active"
I don't know how to check user details for reflesh token with no username and password?
Or what is the correct steps to configure Jdbc?

Trying to use an html page to get OAuth code instead of curl

This repo has been very helpful in learning about OAuth so thank you!

I am understanding the process of getting a code with the terminal commands, but I was trying to do this by using an html login page. Have any quick advice on using a login page to get the OAuth code and authenticate a user?

Thanks again.

Adding new users

Hi - I have this working nicely but want to be able to add new users. I can't work out how to get the entries into the table that maps users to roles. If I try to save the object without the role mapping I get a constraint violation but the id is only set on save so how can I do this? Any advice greatly appreciated.

Thanks

Anthony

@EnableWebMvcSecurity is deprecared

I was looking into the code and saw the "@EnableWebMvcSecurity" annotation. I am fairly new to Spring so I went online to find out what it does but it seems to be deprecated as of spring 4.0
(http://docs.spring.io/autorepo/docs/spring-security/4.0.x/reference/html/mvc.html)

If I remove the annotation the greetingAuthorized test fails, do you have any idea on how to fix this?

java.lang.AssertionError: JSON path$.content
Expected: is "Hello, Roy!"
     but: was "Hello, null!"
    at org.springframework.test.util.MatcherAssertionErrors.assertThat(MatcherAssertionErrors.java:80)
    at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:92)
    at org.springframework.test.web.servlet.result.JsonPathResultMatchers$1.match(JsonPathResultMatchers.java:56)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:152)
    at hello.GreetingControllerTest.greetingAuthorized(GreetingControllerTest.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Getting to work with Forms

First thanks for this sample it was very helpful and one of the few working samples I could find with Spring Boot and OAuth2. Is there a way to get this to work alongside Spring Form authentication?

.formLogin().loginPage("/login").permitAll().and().logout().permitAll().and()

Getting the following error:
An Authentication object was not found in the SecurityContext

If Gson mapper is chosen, the oauth token response is empty

If I add spring.http.converters.preferred-json-mapper=gson to application.properties and add the gson dependency, the oauth token is not returned.

Removing the spring.http.converters.preferred-json-mapper=gson from the properties makes it work again. Any ideas? I want to use gson for all return types.

how to avoid password from serialization in User entity

This is more of a question.

I do not want the password of user available in controller. After making the following change to the controller, I see the password of the User returned.

@RestController
public class GreetingController {

    private static final String template = "Hello, %s! your password is %s";

    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@AuthenticationPrincipal User user) {
        return new Greeting(counter.incrementAndGet(), String.format(template, user.getName(),user.getPassword()));
    }

}

In order to avoid password, I add the following in the User Entity.

@Entity
public class User {

    ......

    @NotEmpty
    @JsonIgnore
    private String password;

       ......
}

I still see the password returned. Any help here will be very useful.

Thanks

UserRepositoryUserDetails has to implement abstract method getPassword

Hi,

I'm trying to use your project as base and I'm getting that UserRepositoryUserDetails has to implement abstract method getPassword. In addition, I don't have methods: getRoles(), getLogin()

I guess it is an issue related to Spring version. Is there anyway to fix it?

Thank you very much!

Project is broken on Spring Boot 1.5.4.RELEASE

I've tested this project with the latest Spring Boot version, and found that this is not work as expected.

1:26:09 โ€บ curl http://localhost:8080 -v
* Rebuilt URL to: http://localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 302
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=6A692E4F63DF7520058169BEEC44E0D2; Path=/; HttpOnly
< Location: http://localhost:8080/login           <------------- This!!!
< Content-Length: 0
< Date: Thu, 22 Jun 2017 17:26:11 GMT
<
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact

We got redirection to /login instead of the unauthorized error.

Steps to reproduce.

  1. Replace Spring Boot version in build.gradle.
buildscript {
	repositories {
		mavenCentral()
		maven { url "https://repo.spring.io/plugins-release" }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.4.RELEASE")
	}
}

// keep the rest
  1. Remove WebInitializer.java, since this cause some issue with latest Boot version.
 rm src/main/java/hello/WebInitializer.java
  1. Run bootRun and send GET request using above curl command.

AJAX call how to pass (-vu clientapp:123456)

HI Roy,

Thank you for spring-rest-service-oauth.

I have small issue when I try to run with curl command its working fine no issues, but when we try to
run with AJAX call how to pass (-vu clientapp:123456), without -vu clientapp:123456 I am getting "Full authentication is required to access this resource", please could you suggest me on this.

I am trying with swagger also, for principal parameter I am passing clientapp:123456, but an getting the same error "Full authentication is required to access this resource".

Thank you

Regards
-Durga K

usage of /oauth/authorize vs /oauth/token ?

This is again a question:

In this excellent material, @royclarkson has shown how to use /aouth/token to get the access token

curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"

I noticed in this tutorial and in here that two steps are involved in getting access token

1. get an access code

 http://localhost:9999/uaa/oauth/authorize?response_type=code&client_id=acme&redirect_uri=http://example.com

2. exchange access code for access token

$ curl acme:acmesecret@localhost:9999/uaa/oauth/token  \
-d grant_type=authorization_code -d client_id=acme     \
-d redirect_uri=http://example.com -d code=jYWioI

(these curls from second link above)

why is that two step process involved? while in this spring-rest-service-oauth, access token is directly retrieved instead of first retrieving code and then exchanging the code for access token.

https support

Thanks for an awesome example !

Could you please extend the source in order to work with oauth2 over https ?

Thanks in advance!

NullPointerException on /oauth/check_token with valid token

NOTE: I'm closing this issue and posting it to the appropriate project.

Hello, I have the following configuration:

@Configuration
@EnableResourceServer
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER-1)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{

    @Autowired
    TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("resource").tokenStore(tokenStore);
    }
}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter{
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(this.authenticationManager)
        .tokenEnhancer(tokenEnhancer())
        .tokenStore(tokenStore());
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .inMemory()
                .withClient("client")
                .secret("secret")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .resourceIds("resource").accessTokenValiditySeconds(60);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception
    {
       oauthServer.checkTokenAccess("isAuthenticated()");    
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

}

Calling /oauth/token returns a token:

curl -u client:secret -X POST http://localhost:8080/oauth/token -H "Accept: application/json" -d "username=user&password=password&grant_type=password"

{"access_token":"941fe30d-9235-46c8-89cf-af7cebd3f7a4","token_type":"bearer","refresh_token":"582338d9-b59e-43d4-a26e-fcb344a801f9","expires_in":59,"scope":"read write","user_name":"user"}

Calling /oauth/check_token with an invalid token returns a non-valid message:

curl -u client:secret -X POST http://localhost:8080/oauth/check_token -H "Accept: application/json" -d "token=519ce11b-bc5d-49c2-b30e-6b6b02ea91b8"

{"error":"invalid_token","error_description":"Token was not recognised"}

Calling /oauth/check_token with an expired token returns an expired message:

curl -u client:secret -X POST http://localhost:8080/oauth/check_token -H "Accept: application/json" -d "token=582338d9-b59e-43d4-a26e-fcb344a801f9"

{"error":"invalid_token","error_description":"Token has expired"}

But calling /oauth/check_token on a valid and non-expired token returns:

curl -u client:secret -X POST http://localhost:8080/oauth/check_token -H "Accept: application/json" -d "token=2e70671b-9f35-4f1a-b2cb-36728703d08b"

{"timestamp":1449164877694,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException","message":"No message available","path":"/oauth/check_token"}

Printing the following stack trace in the console:

java.lang.NullPointerException: null
    at org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(CheckTokenEndpoint.java:84) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:242) ~[spring-boot-actuator-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:111) ~[spring-boot-actuator-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:213) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103) ~[spring-boot-actuator-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]

Question trying this w/ existing project

Hi, - so I have an existing SpringBoot project.

a) I added this at the top of my main @configuration class

@Import({ WebSecurityConfiguration.class, OAuth2ServerConfiguration.class })

b) The contents of the above 2 classes are the same as what is in this project

c) I startup my app and see this as expected in the logs:

2015-10-28 20:05:40,037 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/authorize]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal) 
2015-10-28 20:05:40,037 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal) 
2015-10-28 20:05:40,040 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/token],methods=[GET]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException 
2015-10-28 20:05:40,040 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/token],methods=[POST]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException 
2015-10-28 20:05:40,041 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/check_token]}" onto public java.util.Map<java.lang.String, ?> org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(java.lang.String) 
2015-10-28 20:05:40,041 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/confirm_access]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception 
2015-10-28 20:05:40,042 INFO [FrameworkEndpointHandlerMapping] Mapped "{[/oauth/error]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint.handleError(javax.servlet.http.HttpServletRequest) 

d) When I go to /greeting I get the following as expected:

{
  "error": "unauthorized",
  "error_description": "Full authentication is required to access this resource"
}

e) When I attempt to POST to /oauth/token I see the below in the logs... but I get a 404 and no token back. This has been driving me nuts now for 2 days trying to figure this out. Any help appreciated.

2015-10-28 20:08:59,713 DEBUG [FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /oauth/token; Attributes: [fullyAuthenticated]
2015-10-28 20:08:59,713 DEBUG [FilterSecurityInterceptor] Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@7159411d: Principal: org.springframework.security.core.userdetails.User@8e81ee76: Username: clientapp; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: USER; 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: USER
2015-10-28 20:08:59,713 DEBUG [AffirmativeBased] Voter: org.springframework.security.web.access.expression.WebExpressionVoter@44aef1f8, returned: 1
2015-10-28 20:08:59,713 DEBUG [FilterSecurityInterceptor] Authorization successful
2015-10-28 20:08:59,713 DEBUG [FilterSecurityInterceptor] RunAsManager did not change Authentication object
2015-10-28 20:08:59,713 DEBUG [FilterChainProxy] /oauth/token reached end of additional filter chain; proceeding with original chain
2015-10-28 20:08:59,714 DEBUG [ExceptionTranslationFilter] Chain processed normally
2015-10-28 20:08:59,714 DEBUG [SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed

Again, I just get a 404

Oauth2RestTemplate example

This is a great example project, but it would be nice to have an example using the OAuth2RestTemplate along with the provided curl example.

What is User credentails to get access token

Hi,

I have checked out the code and tried executing in my local, however I am getting response as Bad Credentials. I am unsure what is the username and password to get the access token ?

Below is the request/response payloads, let me know if I am wrong anywhere.
curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"

{"error":"invalid_grant","error_description":"Bad credentials"}

Can you please guide what could be wrong in the above request.

~MS

JDBC

Hi Roy!

So say i wan't to create an application with like 100 users with different user roles.
I want to create the users in a MySQL database and use them, I want also be able to "backtrace" an oath to see which privileges the user have. Would be awesome if you could show an example for this.

Thanks

//John

UserDetailsService is required for two providers

I am facing a similer error to issues-19 but in my case i do have two provider ldap and dao thus two UserDetailsService so i was not able to explicity set the sugessted solution in issue 19 .

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(daoUserDetailsService());
        return daoAuthenticationProvider;
    }
	@Bean
	@Autowired
	public LdapAuthenticationProvider ldapAuthenticationProvider(AbstractLdapAuthenticator authenticatorWithIP,LdapAuthoritiesPopulator authoritiesPopulator,LdapUserDetailsMapper adLdapUserDetailsMapper) {

		LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(authenticatorWithIP, authoritiesPopulator);
				
		ldapAuthenticationProvider.setUserDetailsContextMapper(adLdapUserDetailsMapper);
		
		return ldapAuthenticationProvider;
	}
   @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider);
        auth.authenticationProvider(ldapAuthenticationProvider);
    }
default/auth-568fc74879-s68hk[auth]: 2018-11-28 10:51:07.767  INFO 1 --- [nio-9191-exec-8] o.s.s.o.p.token.store.JdbcTokenStore     : Failed to find access token for token ed32b91a-fc00-4095-b891-091e92282d04
default/auth-568fc74879-s68hk[auth]: 2018-11-28 10:51:22.006 ERROR 1 --- [nio-9191-exec-9] o.s.s.o.provider.endpoint.TokenEndpoint  : Handling error: IllegalStateException, UserDetailsService is required.
default/auth-568fc74879-s68hk[auth]:
default/auth-568fc74879-s68hk[auth]: java.lang.IllegalStateException: UserDetailsService is required.
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:463)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:68)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider.authenticate(PreAuthenticatedAuthenticationProvider.java:103)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.provider.token.DefaultTokenServices.refreshAccessToken(DefaultTokenServices.java:150)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter.getAccessToken(RefreshTokenGranter.java:47)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.provider.token.AbstractTokenGranter.grant(AbstractTokenGranter.java:65)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.provider.CompositeTokenGranter.grant(CompositeTokenGranter.java:38)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer$4.grant(AuthorizationServerEndpointsConfigurer.java:561)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(TokenEndpoint.java:132)
default/auth-568fc74879-s68hk[auth]: 	at sun.reflect.GeneratedMethodAccessor136.invoke(Unknown Source)
default/auth-568fc74879-s68hk[auth]: 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
default/auth-568fc74879-s68hk[auth]: 	at java.lang.reflect.Method.invoke(Method.java:498)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
default/auth-568fc74879-s68hk[auth]: 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
default/auth-568fc74879-s68hk[auth]: 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:60)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:215)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
default/auth-568fc74879-s68hk[auth]: 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
default/auth-568fc74879-s68hk[auth]: 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

Deployed in AWS Elastic Beanstalk

Hi,
Does this configuration work properly in AWS with a balancer ahead? To properly functioning balancing would have to be in session and not by requests. The access token access is stored in the memory of each instance, once the access token has been assigned to the user all requests would have to go to the same instance.
I hope I explained :-)
Thank you!

Custom Access and Refresh OAuth2 Token ?

Hey guys,

I know those token spring generates a UUID formatted string. One of my concerns is that it's not really "unique"; it is possible for the UUID to create a token exactly the same as a previous one (of course the odds are VERY small but still possible).

I'm using a database to store my user's token and I'm not sure if Spring checks if the token already exists before creating one in the database?

My second question is : Is it possible to create my own token instead of the UUID format, I'd like to have a more "unique" token like the current timestamp with the user's ID and username and then hash everything and that will be my token instead of 49784c38-43b1-.....

I already have a custom TokenEnhancer that I use to add custom info when returning the token to the client but how can I create a custom token before saving it in my database?

Thanks for you help!

'entityManagerFactory' in your configuration.

Description:

Parameter 0 of constructor in com.template.webserver.CustomUserDetailsService required a bean named 'entityManagerFactory' that could not be found.

Action:

Consider defining a bean named 'entityManagerFactory' in your configuration.

Can you please help. me to solve this problem.

How to use refresh token?

Hi Roy,

Thanks for the excellent example, Its perfect and working fine.
I just wanna know how to use refresh tokens in this example.
Currently its not providing refresh token, if authentication token expired, I have to call authentication URL and retrieve the token back.
Instead i would like to use refresh token to retrieve new tokens. Please provide us some examples.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.