Spring oauth2 授权服务器上的 /oauth/token 请求“需要完全身份验证才能访问此资源”

问题描述 投票:0回答:1

我正在尝试创建一个页面来保存一些可以通过某些客户端网页访问的用户数据。这让我接触到了 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 / client,但使用授权服务器给出的代码),但现在有附加选项单击另一个已返回代码的链接 (localhost:8081/oauth/token...)。所有这些都有效,但是当用户单击第二个链接并重定向到授权服务器时,该身份验证服务器会响应“访问此资源需要完全身份验证”。

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

对于这个问题你有什么想法吗?

spring authentication oauth-2.0 spring-security-oauth2
1个回答
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>
© www.soinside.com 2019 - 2024. All rights reserved.