Я настраиваю свой Сервер авторизации OAuth2 (тип предоставления пароля) для межмикросервисной связи.
Мне нужно аутентифицировать пользователя, но мне также нужен байтовый массив для аутентификации, отличной от имени пользователя / пароля.
Согласно Spring * do c, я пытаюсь добавить custom AuthenticationProvider
. Поэтому я делаю следующее:
1) Создайте CustomAuthenticationToken
для авторизации этого запроса, расширяя UsernamePasswordAuthenticationToken
дополнительным содержимым байтового массива:
public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken {
private final Object principal;
private Object credentials;
private byte[] customBytes;
public CustomAuthenticationToken(Object principal, Object credentials) {
super(principal, credentials);
this.principal = principal;
this.credentials = credentials;
}
public void setImageBytes(byte[] customBytes) {
this.customBytes = customBytes;
}
public byte[] getImageBytes() {
return customBytes;
}
...
2) Создайте пользовательский Фильтр TokenEndpointAuthenticationFilter
, который может захватывать эти байты из HttpRequest
и создавать объект CustomAuthenticationToken
выше. Я также установил SecurityContextHolder
для использования этого объекта для аутентификации.
public class CustomTokenEndpointAuthenticationFilter extends TokenEndpointAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final OAuth2RequestFactory oAuth2RequestFactory;
public CustomTokenEndpointAuthenticationFilter(AuthenticationManager authenticationManager, OAuth2RequestFactory oAuth2RequestFactory) {
super(authenticationManager, oAuth2RequestFactory);
this.authenticationManager = authenticationManager;
this.oAuth2RequestFactory = oAuth2RequestFactory;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
CustomAuthenticationToken customAuth = new CustomAuthenticationToken(username, password);
customAuth.setCustomBytes(getBytesFromHttpRequest...);
SecurityContextHolder.getContext().setAuthentication(customAuth);
chain.doFilter(req, response);
}
}
3) Затем подключите этот новый фильтр конечных точек токенов как часть конфигурации сервера авторизации:
@Configuration
public class OAuth2SecurityConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
.addTokenEndpointAuthenticationFilter(new CustomTokenEndpointAuthenticationFilter(authenticationManager, null));
}
Однако я получаю эту ошибку:
[org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken]
Система все еще ожидает AuthenticationProvider
для UsernamePasswordAuthenticationToken
, когда я не буду использовать sh.
У объекта UsernamePasswordAuthenticationToken
есть объект details
, но его нельзя использовать для хранения байтовых массивов, поскольку он имеет тип LinkedHashMap<String, String>
.
. использовать пользовательскую аутентификацию для конечной точки токена сервера авторизации для типа предоставления пароля OAuth2 с дополнительной информацией для аутентификации в виде байтовых массивов (поверх имени пользователя / пароля).