[英]spring-oauth2 login success handler
有沒有一種方法可以使用spring-oauth2添加登錄成功處理程序?
我嘗試使用基本身份驗證篩選器,但它僅篩選客戶端憑據而不篩選用戶憑據。
還是我需要創建一個自定義用戶身份驗證管理器?
TIA
此解決方案適用於密碼流,但我不確定其他解決方案。 您可以在oauth-server配置中的http標記中的“ before = BASIC_AUTH_FILTER”位置添加自定義過濾器,並且可以通過解析“ oauth / token”的響應來實現,因此創建ByteArrayResponseWrapper以獲得響應,這里我使用的是TeeOutputStream “ 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();
}
}
並且我創建了令牌提取器來分離提取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;
}
}
在創建過濾器后,像這樣覆蓋doFilter
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) {
}
在創建過濾器實例時注入tokenServices。 現在將根據您的身份驗證調用onSuccessfulClientAuthentication,onFailClientAuthentication,onSuccessfulUserAuthentication和onFailureUserAuthentication
有關更多信息,您可以在github上引用此代碼
編輯:
當您具有默認令牌響應並且僅使用ServletResponseWrapper和提取時,上述代碼片段可以正常工作。 但它似乎仍然很脆弱,因此您可以通過org.springframework.security.oauth2.provider.token.TokenEnhancer
類來了解用戶身份驗證成功
遵循此答案以獲取詳細信息。
我們構建了一個自定義身份驗證管理器,將其連接到OAuth2AuthenticationProcessingFilter即可完成此操作。 管理員的authenticate方法能夠從身份驗證主體中解壓縮OAuth2Authentication和OAuth2AuthenticationDetails。
<bean id="oAuth2AuthenticationManager" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager">
<property name="resourceId" value="XXX-api"/>
<property name="tokenServices" ref="tokenServices"/>
</bean>
<bean id="resourceServerFilter"
class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter">
<property name="authenticationManager" ref="oAuth2AuthenticationManager"/>
<property name="tokenExtractor">
<bean class="com.xxx.oauth.BearerTokenExtractor"/>
</property>
</bean>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.