资源服务器上的Spring Boot OAuth2问题

时间:2019-12-18 19:29:53

标签: java spring-boot spring-security

嗨,我正在尝试实现一个Spring Boot Resource Server,它可以从我的身份验证服务器检查令牌。

我遇到的问题是我在令牌验证中不断遇到错误

{"error":"invalid_token","error_description":"e9d5029d-8f2a-4001-98dd-d6d6afb4f8c3"}

我正在与资源服务器在同一台计算机上运行身份验证服务器。测试时,请执行以下步骤:

1)通过以下方式请求令牌:curl -X POST http://localhost:9999/oauth/token --header "Authorization:Basic YXBwY2xpZW50OmFwcGNsaWVudEAxMjM=" -d "grant_type=password" -d "username=john" -d "password=john@123"

2)然后,我可以验证令牌curl -X POST http://localhost:9999/oauth/check_token -d "token=e9d5029d-8f2a-4001-98dd-d6d6afb4f8c3"

3)然后,我尝试将请求发送到资源服务器以访问页面, curl -X GET http://localhost:8010/favouritePet --header "Authorization:Bearer e9d5029d-8f2a-4001-98dd-d6d6afb4f8c3"

返回{"error":"invalid_token","error_description":"e9d5029d-8f2a-4001-98dd-d6d6afb4f8c3"}

我希望有人可以看到问题所在:)

资源服务器上的调试控制台

2019-12-18 20:09:51.722  INFO 7436 --- [nio-8010-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-12-18 20:09:51.722  INFO 7436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-12-18 20:09:51.722 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : Detected StandardServletMultipartResolver
2019-12-18 20:09:51.730 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : enableLoggingRequestDetails='true': request parameters and headers will be shown which may lead to unsafe logging of potentially sensitive data
2019-12-18 20:09:51.730  INFO 7436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
2019-12-18 20:09:51.772 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.client.RestTemplate              : HTTP POST http://localhost:9999/oauth/check_token
2019-12-18 20:09:51.784 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.client.RestTemplate              : Accept=[application/json, application/*+json]
2019-12-18 20:09:51.786 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.client.RestTemplate              : Writing [{token=[e9d5029d-8f2a-4001-98dd-d6d6afb4f8c3]}] as "application/x-www-form-urlencoded"
2019-12-18 20:09:51.837 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.client.RestTemplate              : Response 200 OK
2019-12-18 20:09:51.838 DEBUG 7436 --- [nio-8010-exec-1] o.s.web.client.RestTemplate              : Reading to [java.util.Map<?, ?>]

身份验证服务器上的调试控制台

2019-12-18 20:09:51.825 DEBUG 22232 --- [nio-9999-exec-3] o.s.web.servlet.DispatcherServlet        : POST "/oauth/check_token", parameters={masked}
2019-12-18 20:09:51.835 DEBUG 22232 --- [nio-9999-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, application/*+json] and supported [application/json, application/*+json, application/json, application/*+json]
2019-12-18 20:09:51.835 DEBUG 22232 --- [nio-9999-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [{aud=[petstore], exp=1576698083, user_name=john, authorities=[AUTHORIZED_PETSTORE_ADMIN, AUTHORIZED_ (truncated)...]
2019-12-18 20:09:51.836 DEBUG 22232 --- [nio-9999-exec-3] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

身份验证服务器

package habuma;

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class JpaConfig {

    @Bean
    public DataSource getDataSource()
    {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.url("jdbc:mysql://192.168.1.38:3306/auth?useLegacyDatetimeCode=false&serverTimezone=UTC");
        dataSourceBuilder.username("xxxxxx");
        dataSourceBuilder.password("xxxxxxxxx");
        dataSourceBuilder.driverClassName(com.mysql.cj.jdbc.Driver.class.getName());
        return dataSourceBuilder.build();
    }
}


package habuma;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

import javax.sql.DataSource;

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

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

    @Autowired
    DataSource dataSource;

    @Qualifier("org.springframework.security.userDetailsService")
    @Autowired
    private UserDetailsService usrSvc;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
           security.checkTokenAccess("isAuthenticated()");
        security.checkTokenAccess("permitAll");
        security.passwordEncoder(clientPasswordEncoder());

    }

    // Configure the token store and authentication manager
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //@formatter:off
        endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).userDetailsService(usrSvc);
        //@formatter:on
    }

    // Configure a client store. In-memory for simplicity, but consider other
    // options for real apps.
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //@formatter:off
        clients.jdbc(dataSource);
    }

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

    @Bean("clientPasswordEncoder")
    PasswordEncoder clientPasswordEncoder() {
        return new BCryptPasswordEncoder(8);
    }

}


package habuma;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OAuthAuthServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OAuthAuthServerApplication.class, args);
    }
}


package habuma;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;

@RestController
@RequestMapping("/principal")
public class rest {

    @GetMapping
    public Principal retrievePrincipal(Principal principal) {
        return principal;
    }
}


package habuma;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> cfg = auth.jdbcAuthentication()
                .passwordEncoder(userPasswordEncoder()).dataSource(dataSource);

        cfg.getUserDetailsService().setEnableGroups(true);
        cfg.getUserDetailsService().setEnableAuthorities(false);

    }

    @Override
    @Bean(BeanIds.USER_DETAILS_SERVICE)
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Bean("userPasswordEncoder")
    PasswordEncoder userPasswordEncoder() {
        return new BCryptPasswordEncoder(4);
    }
}

资源服务器

package com.Cleverparking.Resource.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@EnableResourceServer
@SpringBootApplication
public class ResourceServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ResourceServerApplication.class, args);
    }

}


package com.Cleverparking.Resource.server;

import org.springframework.boot.actuate.trace.http.HttpTrace;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class RestControllerURI {

    @GetMapping("pet")
    @PreAuthorize("hasAuthority('AUTHORIZED_PETSTORE_USER')")
    public String pet(HttpTrace.Principal principal) {
        return "Hi " + principal.getName() + ". My pet is dog";
    }

    @GetMapping("hello")
    public String hello(HttpStatus status){
        return status.toString();
    }


    @GetMapping("favouritePet")
    @PreAuthorize("hasAuthority('AUTHORIZED_PETSTORE_ADMIN')")
    public String favouritePet(HttpTrace.Principal principal) {
        return "Hi " + principal.getName() + ". My favourite pet is cat";
    }

}


package com.Cleverparking.Resource.server;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
//@Order(SecurityProperties.BASIC_AUTH_ORDER)

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}


server.port=8010

security.oauth2.client.client-id=appclient
security.oauth2.client.client-secret=appclient@123
security.oauth2.resource.id=petstore

security.oauth2.resource.token-info-uri=http://localhost:9999/oauth/check_token

logging.level.org.springframework.web= DEBUG
logging.level.org.hibernate= DEBUG
spring.http.log-request-details=true

0 个答案:

没有答案