To rozwiązanie będzie działało na rzecz przepływu haseł, a dla innych nie jestem pewien. Możesz dodać swój filtr niestandardowy w pozycji "before = BASIC_AUTH_FILTER" w znaczniku http, który znajduje się w konfiguracji serwera auauth, i możesz to osiągnąć, analizując odpowiedź "oauth/token", a następnie utwórz ByteArrayResponseWrapper, aby uzyskać odpowiedź, Tutaj używam klasy TeeOutputStream z "org.apache.commons commons-IO",
private class ByteArrayResponseWrapper extends HttpServletResponseWrapper {
public ByteArrayResponseWrapper(ServletResponse response) {
super((HttpServletResponse) response);
}
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(new TeeOutputStream(
super.getOutputStream(), byteArrayOutputStream));
}
public byte[] getByteArray() {
return this.byteArrayOutputStream.toByteArray();
}
}
i ja stworzyliśmy tokena ściągacza oddzielić kod wydobycia access_token
public class OAuth2AccessTokenExtractor implements
OAuth2AccessTokenExtractor {
private ObjectMapper mapper = new ObjectMapper();
public String getAccessTokenValue(byte[] response) {
try {
return mapper.readValue(response, OAuth2AccessToken.class)
.getValue();
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
po utworzyć filtr nadpisywania doFilter jak to
private DefaultTokenServices tokenServices;
private OAuth2AccessTokenExtractor tokenExtractor;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// create wrapper to read response body
ByteArrayResponseWrapper responseWraper = new ByteArrayResponseWrapper(
response);
// led them go
chain.doFilter(request, responseWraper);
// get ClientAuthentication
Authentication clientAuthentication = SecurityContextHolder
.getContext().getAuthentication();
// is authenticated or not to proceed
if (clientAuthentication != null
&& clientAuthentication.isAuthenticated()) {
// callBack client authenticated successfully
onSuccessfulClientAuthentication(request, response,
clientAuthentication);
// check response status is success of failure
if (responseWraper.getStatus() == 200) {
// extract accessToken from response
String token = tokenExtractor
.getAccessTokenValue(responseWraper.getByteArray());
if (token != null && !token.isEmpty()) {
// load authentication from token
OAuth2Authentication oAuth2Authentication = this.tokenServices
.loadAuthentication(token);
OAuth2AccessToken actualAccessToken = this.tokenServices
.getAccessToken(oAuth2Authentication);
// callBack user authenticated successfully
onSuccessfulUserAuthentication(request, response,
clientAuthentication, oAuth2Authentication,
actualAccessToken);
} else {
log.error("access token is empty from extractor");
}
} else {
// callBack user authenticated failure
onFailureUserAuthentication(request, response,
clientAuthentication, request.getParameter("username"));
}
} else {
// callBack client authenticated failure
onFailClientAuthentication(request, response,
request.getParameter(OAuth2Utils.CLIENT_ID));
}
}
protected void onSuccessfulClientAuthentication(ServletRequest request,
ServletResponse response, Authentication authentication) {
}
protected void onFailClientAuthentication(ServletRequest request,
ServletResponse response, String clientId) {
}
protected void onSuccessfulUserAuthentication(ServletRequest request,
ServletResponse response, Authentication clientAuthentication,
OAuth2Authentication userOAuth2Authentication,
OAuth2AccessToken token) {
}
protected void onFailureUserAuthentication(ServletRequest request,
ServletResponse response, Authentication clientAuthentication,
String username) {
}
podczas tworzenia instancji filtru wstrzyknij tokenServices. teraz onSuccessfulClientAuthentication, onFailClientAuthentication, onSuccessfulUserAuthentication i onFailureUserAuthentication będzie nazywany w zależności uwierzytelniania
dłużej można odwołać ten kod na github
edycja:
Powyższy fragment działa dobrze, gdy masz domyślne token response i po prostu używa ServletResponseWrapper i wyodrębniania. Ale nadal wygląda na podatną na uszkodzenia, dzięki czemu można poznać sukces uwierzytelnienia użytkownika poprzez org.springframework.security.oauth2.provider.token.TokenEnhancer
klasa
Aby uzyskać szczegółowe informacje, należy postępować zgodnie z tym answer.
Dzięki. To jest ponade mnie, dlaczego autorzy wiosną oauth2 złamali sprawdzony projekt z prostymi narzędziami do sukcesów/niepowodzeń, które sprawdziły się tak dobrze w przeszłości. –