我们构建了一个定制的身份验证管理器,并将其连接到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>
这个解决方案将适用于密码流和其他我不确定的问题。您可以在oauth服务器配置中的http标记中的“before=BASIC_AUTH_filter”位置添加自定义过滤器,您可以通过解析“oauth/token”的响应来实现,因此创建ByteArrayResponseWrapper来获得响应,这里我使用的是“org.apache.commons-io”中的TeeOutputStream类,
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();
}
}
我创建了令牌提取器来分离提取访问令牌的代码
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) {
}
在创建过滤器实例时注入令牌服务。现在将根据您的身份验证调用onSuccessfulClientAuthentication、onFailClientAuthentication、onSuccessfulUserAuthentication和onFailureUserAuthentication
有关更多信息,您可以在github上参考此代码
编辑:
当你有默认的令牌响应时,上面的片段可以正常工作,它只是使用ServletResponse seWrapper和提取。但它仍然看起来很脆弱,所以你可以通过了解用户身份验证成功org.springframework.security.oauth2.provider.token.Token增强器
类
请按照此答案了解详细信息。
是否可以为Spring Oauth2 Sso服务设置默认登录成功URL? 紧随塞纳里奥 null 有没有一种方法可以不重定向到上一个受保护的请求的资源,而是默认情况下重定向到'index.html'? 请让我知道,即使没有办法实现这一点
这是application.properties文件的一部分: 一旦登录,用户可以调用这个url/users/{username},但是当他通过OAuth2登录facebook或google时,他会被拒绝,因为权威列表是空的。当他用他的webapp凭据登录时,权威列表包含USER_ROLE,他可以继续操作。 主体对象内部有: null null
我试图在登录symfony2应用程序后实现重定向,以便在我的用户是否有一个属性时重定向。我已在项目的Handler文件夹中创建了AuthenticationSuccessHandler.php类: 但是当我登录时,我得到一个错误: 注意:未定义的属性:Me\MyBundle\Handler\AuthenticationSuccessHandler::$router in/var/www/MyBun
我刚刚在这个论坛的帮助下添加了一个AuthenticationSuccessHandler,当用户通过fosuserbundle或fosfacebookbundle登录时,它在我的站点上实现了重定向。当用户完成或未完成配置文件时,重定向会发生变化,如果已经完成,我希望将它们重定向到以前的位置,这就是我使用referer变量的原因。 security.yml,我已在fos_facebook和form
问题内容: 我的应用程序中有Facebook登录名,并且我正在圈子里奔波,试图让需要通过注册屏幕的新用户和应该直接进入应用程序的注册用户保持平衡。这是处理Facebook登录的功能(当点击按钮并获得Facebook授权时): 在上面的方框中,我基本上说的是,一旦点击Facebook登录按钮并经过Facebook授权,如果用户具有访问令牌,则直接进入应用程序。否则,请转到注册屏幕,用户将在其中输入必
在web.xml中,我有以下内容