Giải pháp này sẽ hoạt động cho lưu lượng mật khẩu và cho những người khác mà tôi không chắc chắn. Bạn có thể thêm bộ lọc tùy chỉnh ở vị trí "before = BASIC_AUTH_FILTER" trong thẻ http có cấu hình oauth-server, và bạn có thể đạt được bằng cách phân tích cú pháp "oauth/token" để tạo ByteArrayResponseWrapper để nhận phản hồi, Tại đây tôi đang sử dụng lớp TeeOutputStream từ "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();
}
}
và tôi đã tạo ra vắt thẻ để tách mã chiết xuất 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;
}
}
sau khi tạo doFilter lọc ghi đè của bạn như này
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) {
}
trong khi tạo mã thông báo cấp phép lọc bộ lọcServices. tại onSuccessfulClientAuthentication, onFailClientAuthentication, onSuccessfulUserAuthentication và onFailureUserAuthentication sẽ được gọi theo ý muốn xác thực của bạn
để biết thêm bạn có thể tham khảo mã này vào github
được sửa đổi:
Đoạn trên hoạt động tốt khi bạn có mặc định token response và nó chỉ sử dụng ServletResponseWrapper và giải nén. Nhưng vẫn có vẻ như dễ bị tổn thương để bạn có thể biết được thành công xác thực người dùng bằng cách thông qua org.springframework.security.oauth2.provider.token.TokenEnhancer
lớp
Làm theo chi tiết answer này để biết chi tiết.
Cảm ơn. Đó là ngoài tôi lý do tại sao các tác giả của oauth2 mùa xuân đã phá vỡ thiết kế đã được chứng minh với thành công đơn giản/xử lý thất bại đã làm việc rất tốt trong quá khứ. –