在/ oauth / token请求

时间:2016-06-07 11:07:07

标签: spring authentication oauth-2.0 spring-security-oauth2

我正在尝试创建一个页面,其中包含可以通过某个客户端网页访问的一些用户数据。这让我想到了oauth2(授权代码)和Spring。目前,我正在根据https://github.com/dynamind/spring-boot-security-oauth2-minimal/以及此工作流https://techannotation.files.wordpress.com/2015/06/oauth2-0-authorization-code.png

为我的代码编写某种概念证据。

我已经拥有一个资源服务器,它使用登录页面对用户进行身份验证,然后让他们可以通过某种方式批准共享他们的数据。然后,它将用户重定向到为客户端设置的页面。

@SpringBootApplication
public class AuthorizationServerApplication extends SpringBootServletInitializer {

    private static final Logger log = LoggerFactory.getLogger(AuthorizationServerApplication.class);

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(AuthorizationServerApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(AuthorizationServerApplication.class);
    }

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        @Autowired // <-- This is crucial otherwise Spring Boot creates its own
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            log.info("Defining inMemoryAuthentication (2 users)");
            auth.inMemoryAuthentication()

                    .withUser("user").password("password").roles("USER")

                    .and()

                    .withUser("admin").password("password").roles("USER", "ADMIN");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()

                    .and()

                    .httpBasic().disable().anonymous().disable().authorizeRequests().anyRequest().authenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

        @Value("${config.oauth2.privateKey}")
        private String privateKey;

        @Value("${config.oauth2.publicKey}")
        private String publicKey;

        @Autowired
        private AuthenticationManager authenticationManager;

        @Bean
        public JwtAccessTokenConverter tokenEnhancer() {
            log.info("Initializing JWT with public key:\n" + publicKey);
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setSigningKey(privateKey);
            converter.setVerifierKey(publicKey);
            return converter;
        }

        @Bean
        public JwtTokenStore tokenStore() {
            return new JwtTokenStore(tokenEnhancer());
        }

        /**
         * Defines the security constraints on the token endpoints
         * /oauth/token_key and /oauth/check_token Client credentials are
         * required to access the endpoints
         *
         * @param oauthServer
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.tokenKeyAccess("isAnonymous() || hasRole('ROLE_TRUSTED_CLIENT')") // permitAll()
                    .checkTokenAccess("hasRole('TRUSTED_CLIENT')"); // isAuthenticated()
        }

        /**
         * Defines the authorization and token endpoints and the token services
         *
         * @param endpoints
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints

                    // Which authenticationManager should be used for the
                    // password grant
                    // If not provided, ResourceOwnerPasswordTokenGranter is not
                    // configured
                    .authenticationManager(authenticationManager)

                    // Use JwtTokenStore and our jwtAccessTokenConverter
                    .tokenStore(tokenStore()).accessTokenConverter(tokenEnhancer());
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()

                    // Public client where client secret is vulnerable (e.g.
                    // mobile apps, browsers)
                    .withClient("clientname") // No secret!
                    .authorizedGrantTypes("authorization_code").scopes("read")
                    .redirectUris("http://localhost:8080/client")

            ;
        }

    }

}

目前我正在处理一个最简单的客户端网页。我创建了一个包含授权服务器链接的页面(localhost:8081 / oauth / authorize ...)。用户点击它并被重定向到授权服务器,在那里登录,批准共享他/她的数据,然后重定向回客户端站点(localhost:8080 /客户端,但授权服务器给出代码),但现在有额外的选项再单击一个已返回代码的链接(localhost:8081 / oauth / token ...)。所有这一切都有效,但是当用户单击此第二个链接并重定向到授权服务器时,此auth服务器会响应“访问此资源需要完全身份验证”。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>client page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="'oooo text oooo'" />
    if you want it
    <a
        th:href="@{http://localhost:8081/oauth/authorize(response_type='code',client_id='client',key='value',scope='read',redirect_uri='http://localhost:8080/client')}">clickit</a>

    <a th:if="${param.code != null}"
        th:href="@{http://localhost:8081/oauth/token(grant_type='authorization_code',code=${param.code[0]},redirect_uri='http://localhost:8080/client')}">
        approve
    </a>
    <div th:if=" ${param.code !=null}
            "
        th:text="${'requestParam: ' + param.code[0]}"></div>

</body>
</html>

你对这个问题有任何想法吗?

1 个答案:

答案 0 :(得分:0)

原来是因为我没有使用POST请求。使用它解决了这个问题:

<form th:if="${param.code != null}"
  th:method="post"
  th:action="@{http://localhost:8081/oauth/token}">
  <input type="text" id="grant_type" name="grant_type" th:value="authorization_code"/>
  <input type="text" id="client_id" name="client_id" th:value="client"/>
  <input type="text" id="code" name="code" th:value="${param.code[0]}"/>
  <input type="text" id="redirect_uri" name="redirect_uri" th:value="@{http://localhost:8080/client}"/>
      <input type="submit" />
</form>