我正在实施一个应用,让我们称之为 OAuth2Client ,其身份验证/授权层通过其他服务器上的spring OAuth2协议实现进行管理, OAuth2Server 。 到目前为止,一切都很好,我只是想转移一下#" normal" OAuth2流程。
例如,在我的第三方应用 OAuth2Client 中,当用户想要登录时,他们必须通过 OAuth2Server 进行身份验证。 然后,我们拥有熟悉的OAuth2流程,用户被重定向到 OAuth2Server 的身份验证页面,输入凭据,被要求获取访问他/她的数据的权限等。
如果身份验证成功,他将被重定向到' redirect_uri'使用身份验证在 OAuth2Client 应用中注册。 '代码'包含在请求中。 OAuth2Client 然后交换此代码'使用'访问令牌'通过api调用 OAuth2Server 上的访问令牌端点。
在用户成功通过身份验证并获得访问令牌后,我想要做的是立即关闭用户会话/身份验证上下文。
我想过使用过滤器,但我不确定这是否是最好的解决方案。
任何帮助将不胜感激 提前谢谢......
答案 0 :(得分:1)
我认为您不能将会话事件附加到/ token端点,但在用户批准授权并发出授权代码后,实际上不再需要会话。所以这会奏效:
@Controller
@SessionAttributes("authorizationRequest")
public class ApprovalEndpoint {
@RequestMapping("/oauth/confirm_access")
public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request, SessionStatus status) throws Exception {
String template = createTemplate(model, request);
if (request.getAttribute("_csrf") != null) {
model.put("_csrf", request.getAttribute("_csrf"));
}
status.setComplete();
return new ModelAndView(new SpelView(template), model);
}
}
或者您可以按照建议使用Filter
,但由于您可能希望自定义用户体验以进行审批,因此您也可以通过此端点进行操作。
答案 1 :(得分:1)
我的oauth客户端设置为autoApprove(true),所以我不能像Dave所说的那样做。 我的解决方案是将/ oauth / authorize映射到另一个端点,并注入起源AuthorizationEndpoint,在起源端点完成工作后,调用request.getSession()。invalidate();
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;
@Controller
@RequestMapping
@SessionAttributes({SessionClosedAuthorizationEndpoint.AUTHORIZATION_REQUEST_ATTR_NAME, SessionClosedAuthorizationEndpoint.ORIGINAL_AUTHORIZATION_REQUEST_ATTR_NAME})
public class SessionClosedAuthorizationEndpoint {
private AuthorizationEndpoint authorizationEndpoint;
@Autowired
public void setAuthorizationEndpoint(AuthorizationEndpoint authorizationEndpoint) {
this.authorizationEndpoint = authorizationEndpoint;
}
static final String AUTHORIZATION_REQUEST_ATTR_NAME = "authorizationRequest";
static final String ORIGINAL_AUTHORIZATION_REQUEST_ATTR_NAME = "org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.ORIGINAL_AUTHORIZATION_REQUEST";
@RequestMapping(value = "/oauth/authorize/custom")
public ModelAndView authorize(HttpServletRequest request, Map<String, Object> model, @RequestParam Map<String, String> parameters, SessionStatus sessionStatus, Principal principal) {
ModelAndView authorize = authorizationEndpoint.authorize(model, parameters, sessionStatus, principal);
request.getSession().invalidate();
return authorize;
}
@RequestMapping(value = "/oauth/authorize/custom", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, ?> model,
SessionStatus sessionStatus, Principal principal){
return authorizationEndpoint.approveOrDeny(approvalParameters,model,sessionStatus,principal);
}
}