Я получаю сообщение об ошибке «Недопустимые учетные данные клиента» при вызове конечной точки oauth2 http://localhost:8080/oauth/token.
Я переопределил поведение по умолчанию при проверке учетных данных клиента с помощью MyClientCredentialsTokenEndpointFilter.На самом деле я просто хочу использовать учетные данные клиента, чтобы узнать источник запроса.Если клиент не отправляет его, я хотел бы сравнить его с моими учетными данными по умолчанию и разрешить продолжить.Я знаю, что это не рекомендуется, но у меня есть такое требование.Для этого мне нужно установить правильный менеджер аутентификации в MyClientCredentialsTokenEndpointFilter.В настоящее время это проверка учетных данных клиента с учетными данными пользователя, который вызывает проблему.Я прошу вас помочь, чтобы я мог создать менеджер аутентификации, используя учетные данные, хранящиеся в ClientDetailsServiceConfigurer, а затем установить его в свой пользовательский фильтр.
Вот моя конфигурация сервера авторизации.Я настроил учетные данные клиента здесь.Здесь, в myClientCredentialsTokenEndpointFilterBean, устанавливается неправильный объект диспетчера аутентификации.
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
static final String CLIEN_ID = "client";
static final String CLIENT_SECRET = "secret";
static final String GRANT_TYPE_PASSWORD = "password";
static final String AUTHORIZATION_CODE = "authorization_code";
static final String REFRESH_TOKEN = "refresh_token";
static final String IMPLICIT = "implicit";
static final String SCOPE_READ = "read";
static final String SCOPE_WRITE = "write";
static final String TRUST = "trust";
static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60;
static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("abc");
return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public MyClientCredentialsTokenEndpointFilter myClientCredentialsTokenEndpointFilterBean(ClientDetailsServiceConfigurer configurer) throws Exception{
MyClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter= new MyClientCredentialsTokenEndpointFilter();
clientCredentialsTokenEndpointFilter.setAuthenticationManager(authenticationManager);
clientCredentialsTokenEndpointFilter.afterPropertiesSet();
return clientCredentialsTokenEndpointFilter;
}
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(CLIEN_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter());
}
}
Вот моя реализация фильтра, где я проверяю учетные данные клиента-
public class MyClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
private static final String CONST_DEFAULT_CLIENT_ID = "my-client";
private final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
public MyClientCredentialsTokenEndpointFilter() {
super("/token");
}
@Override
public Authentication attemptAuthentication(final HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
TokenRequestParameters params = null;
try {
params = (TokenRequestParameters)converter.read(TokenRequestParameters.class, inputMessage);
}catch(Exception e) {
logger.error("Failed to parse parameters : " + e.getLocalizedMessage());
throw new BadCredentialsException(e.getMessage());
}
String clientId = params.getClientId() != null ? params.getClientId() : CONST_DEFAULT_CLIENT_ID;
String clientSecret = "secret";
// If the request is already authenticated we can assume that this filter is not needed
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
return authentication;
}
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,
clientSecret);
System.out.println("authResult::111111111");
Authentication authResult = this.getAuthenticationManager().authenticate(authRequest);
System.out.println("authResult::"+authResult);
SecurityContextHolder.getContext().setAuthentication(authResult);
return authResult;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequestWrapper reqWrapper = new CachedInputStreamHttpServletRequestWrapper((HttpServletRequest)req);
super.doFilter(reqWrapper, res, chain);
}
}
Вот моя конфигурация сервера ресурсов-
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.authorizeRequests()
.antMatchers("/users/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
Вот моя конфигурация безопасности -
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource(name = "userService")
private UserDetailsService userDetailsService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api-docs/**").permitAll();
}
@Bean
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder(4);
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Пожалуйста, дайте мне знать, как правильно зарегистрировать диспетчер аутентификации, чтобы учетные данные были проверены по учетным данным клиента.