问题
授权服务器基于Spring Cloud Oauth2创建后,配置TokenStore为JwtTokenStore,访问/oauth/token_key接口获取公钥,出现404错误。
授权服务器配置如下。
package com.luas.xmall.auth.configuration;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import org.springframework.http.HttpMethod;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.oauth2.config.annotation.builders.JdbcClientDetailsServiceBuilder;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.ClientDetails;import org.springframework.security.oauth2.provider.ClientDetailsService;import org.springframework.security.oauth2.provider.ClientRegistrationException;import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;import org.springframework.security.oauth2.provider.endpoint.TokenKeyEndpoint;import org.springframework.security.oauth2.provider.token.TokenStore;import org.springframework.security.oauth2.provider.token.store.*;import javax.sql.DataSource;import java.security.KeyPair;@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserDetailsService userDetailsService; @Autowired private AuthenticationManager authenticationManager; @Autowired private DataSource dataSource; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security. allowFormAuthenticationForClients() .tokenKeyAccess("permitAll()") .checkTokenAccess("permitAll()") ; } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService) .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST) .accessTokenConverter(jwtAccessTokenConverter()) .tokenStore(new JwtTokenStore(jwtAccessTokenConverter())); ; } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // 配置方法1,只需配置DataSource即可,其它交给框架自动配置 clients.jdbc(dataSource).passwordEncoder(passwordEncoder); } private JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setKeyPair(keyPair()); return jwtAccessTokenConverter; } private KeyPair keyPair() { return new KeyStoreKeyFactory(new ClassPathResource("xxx.jks"), "123456".toCharArray()).getKeyPair("xxx", "123456".toCharArray()); }}
分析
先检查授权服务器配置,是否将该端点放开。本例配置中,此端点已为公共端点。
查看授权服务器端点配置类AuthorizationServerEndpointsConfiguration,发现其中只有授权端点、token端点、token校验端点的定义,并无token_key相关端点的定义。
查看token key端点类TokenKeyEndpoint,也并无异常。
![4987d23bbe20c83a4d62fbe1c420a6a1.png](https://i-blog.csdnimg.cn/blog_migrate/5ec7a2722ff7aada529de53e8d7bffc0.jpeg)
解决
基于以上分析,可以大胆猜测,加上端点404报错,应该是没有注册到容器中。那么我们仿照授权端点、token端点、token校验端点的定义,在授权服务器配置中,添加token key端点的定义。
@Beanpublic TokenKeyEndpoint tokenKeyEndpoint() { return new TokenKeyEndpoint(jwtAccessTokenConverter());}
重启服务,再次访问端点,已可以正常展示公钥信息。
![913b688dc3b1013f254e5b6eff812929.png](https://i-blog.csdnimg.cn/blog_migrate/31de7fb1e4ace5e06d0e20c9ad5ff32f.jpeg)