如何关闭用户会话/身份验证。在Spring OAuth2中为用户/客户端发送访问令牌之后的上下文

时间:2015-04-20 14:41:01

标签: java spring spring-security spring-security-oauth2

我正在实施一个应用,让我们称之为 OAuth2Client ,其身份验证/授权层通过其他服务器上的spring OAuth2协议实现进行管理, OAuth2Server 。 到目前为止,一切都很好,我只是想转移一下#" normal" OAuth2流程。

例如,在我的第三方应用 OAuth2Client 中,当用户想要登录时,他们必须通过 OAuth2Server 进行身份验证。 然后,我们拥有熟悉的OAuth2流程,用户被重定向到 OAuth2Server 的身份验证页面,输入凭据,被要求获取访问他/她的数据的权限等。

如果身份验证成功,他将被重定向到' redirect_uri'使用身份验证在 OAuth2Client 应用中注册。 '代码'包含在请求中。 OAuth2Client 然后交换此代码'使用'访问令牌'通过api调用 OAuth2Server 上的访问令牌端点。

在用户成功通过身份验证并获得访问令牌后,我想要做的是立即关闭用户会话/身份验证上下文

我想过使用过滤器,但我不确定这是否是最好的解决方案。

任何帮助将不胜感激 提前谢谢......

2 个答案:

答案 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);
    }

}