成功完成oauth2登录后,我需要访问令牌才能进一步调用Spotify API。我不确定如何获取访问令牌。 Spring Boot以某种方式调用令牌服务URL来与访问令牌交换状态参数(我已经在application.properties中定义了令牌URL)。唯一的问题是,我不确定收到OAuth2AccessTokenResponse时该从哪里获取。 我检查了日志,得到响应对象
elif
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final ObjectMapper mapper;
private final TokenStore tokenStore;
private final TokenFilter tokenFilter;
public SecurityConfig(ObjectMapper mapper, TokenStore tokenStore,
TokenFilter tokenFilter) {
this.mapper = mapper;
this.tokenStore = tokenStore;
this.tokenFilter = tokenFilter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().and().authorizeRequests()
.antMatchers("/oauth2/**", "/login**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.authorizationRequestRepository(new InMemoryRequestRepository())
.and()
.successHandler(this::successHandler)
.and()
.exceptionHandling()
.authenticationEntryPoint(this::authenticationEntryPoint)
.and().logout(cust -> cust.addLogoutHandler(this::logout).logoutSuccessHandler(this::onLogoutSuccess));
http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
}
private void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
// You can process token here
System.out.println("Auth token is - " + request.getHeader("Authorization"));
}
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// this code is just sending the 200 ok response and preventing redirect
response.setStatus(HttpServletResponse.SC_OK);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
private void successHandler(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException {
String token = tokenStore.generateToken(authentication);
response.getWriter().write(
mapper.writeValueAsString(Collections.singletonMap("accessToken", token))
);
}
private void authenticationEntryPoint(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(mapper.writeValueAsString(Collections.singletonMap("error", "Unauthenticated")));
}
}
public class InMemoryRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {
private final Map<String, OAuth2AuthorizationRequest> cache = new HashMap<>();
@Override
public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {
String state = request.getParameter("state");
if (state != null) {
return removeAuthorizationRequest(request);
}
return null;
}
@Override
public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest,
HttpServletRequest request, HttpServletResponse response) {
String state = authorizationRequest.getState();
cache.put(state, authorizationRequest);
}
@Override
public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) {
String state = request.getParameter("state");
if (state != null) {
return cache.remove(state);
}
return null;
}
}
@Component
public class TokenFilter extends OncePerRequestFilter {
private final TokenStore tokenStore;
public TokenFilter(TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authToken = request.getHeader("Authorization");
if (authToken != null) {
String token = authToken.split(" ")[1];
Authentication authentication = tokenStore.getAuth(token);
if (authentication != null) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}