我正在为我正在进行的项目寻求帮助。这是一个Spring Boot项目,我已经实现了Spring Boot Security OAuth2,当OAuth2挂载在根(http://localhost:8080/oauth/token)上时,一切正常,但我需要通过(http://localhost:8080/cranoo/api/v1/oauth/token)访问所有内容,所以我在网上读到,我必须改变AuthorizationServerEndpointsConfigurer bean的映射。在我这样做之后,OAuth2工作正常但其他端点(如用户帐户端点)不起作用。所以我找到了一种使用ServletRegistrationBean配置所有端点的方法,并且这些端点可以工作,但OAuth2令牌端点停止工作并返回401.我希望当ServletRegistrationBean配置为映射时,来自应用程序的所有内容都应该挂载在这些映射上但是事实并非如此。
下面是Dispatcher servlet的代码。
@Bean
public ServletRegistrationBean dispatcherServletRegistration() {
Collection<String> mappings = new ArrayList<String>();
mappings.add("/cranoo/api/v1/*");
ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet());
registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
registration.setUrlMappings(mappings);
return registration;
}
预计会通过http://localhost:8080/cranoo/api/v1访问所有端点,但当我使用postman访问http://localhost:8080/cranoo/api/v1/oauth/token时,它会返回401 Unauthorized“访问此资源需要完全身份验证” 但是,当我访问http://localhost:8080/cranoo/api/v1/cities时,它可以工作,我会得到所有城市的列表。
下面是我的WebSecurityConfigurerAdapter bean。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
static final String SIGNING_KEY = "anietie100THjjj";
static final Integer ENCODING_STRENGTH = 256;
static final String SECURITY_REALM = "Sprinb Boot JWT Example Realm";
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new ShaPasswordEncoder(ENCODING_STRENGTH));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/metrics/**", "/actuator/**", "/api-docs/**", "/login", "/register", "/oauth/token").permitAll()
.and()
.httpBasic()
.realmName(SECURITY_REALM)
.and()
.csrf()
.disable();
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
以下是我的AuthorizationServerEndpointsConfigurer代码。
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
String context = "/cranoo/api/v1";
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints.pathMapping("/oauth/token", context + "/oauth/token");
endpoints.pathMapping("/oauth/authorize", context + "/oauth/authorize");
endpoints.pathMapping("/oauth/confirm_access", context + "/oauth/confirm_access");
endpoints.pathMapping("/oauth/check_token", context + "/oauth/check_token");
endpoints.pathMapping("/oauth/token_key", context + "/oauth/token_key");
endpoints.pathMapping("/oauth/error", context + "/oauth/error");
endpoints.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.tokenEnhancer(enhancerChain)
.authenticationManager(authenticationManager);
}
我的想法是,因为我已经在DispatcherServlet上为整个应用程序配置了映射,所以我不应该再将这些端点映射到AuthorizationServerEndpointsConfigurer上,但即使我删除了上面的所有映射,它仍然没有工作。它仍然返回401.我需要帮助,因为我花了大约四天时间没有进展。 我想要的是能够访问(http://localhost:8080/cranoo/api/v1/oauth/token和(http://localhost:8080/cranoo/api/v1/ {endpoint}
处的其他端点处的令牌端点)