如何实现对接OAuth2协议的应用认证Client端?

一. 前言

本文主要用于介绍如何开发与赛赋IDaaS对接OAuth2协议Client的方法。
html

二. 关于OAuth2

OAuth是Open Authorization的简写。OAuth协议为用户资源的受权提供了一个安全的、开放而又简易的标准。同时,任何第三方均可以使用OAUTH认证服务,任何服务提供商均可以实现自身的OAuth认证服务,于是OAuth是开放的。业界提供了OAuth的多种实现如PHP、JavaScript,Java,Ruby等各类语言开发包,大大节约了程序员的时间,于是OAuth是简易的。
OAuth2是OAuth协议的2.0版本,不向后兼容OAuth1.0。
OAuth 2.0定义了四种受权方式,赛赋IDaaS使了其中的受权码模式(authorization code)
OAuth流程图 (1).png
更新关于OAuth的信息可查看OAuth官网,地址: https://oauth.net/2/
git

三. 实现Client

实现Client的主要思路:程序员

  • 须要新建一个处理redirectUri的controller或者filter进行处理
  • 根据authentication code去请求token
  • 获取token以后将token与用户绑定
  • 以后就能够使用token去获取受权的资源

  下面的连接介绍的比较完整,能够参考:
  https://www.cnblogs.com/linianhui/p/oauth2-authorization.html#auto_id_7github

  • 新建一个登陆的拦截器检验用户是否登陆,未登陆走应用auth2的登陆流程
  • 新建一个处理auth2的登陆流程controller类
  • 判断authentication  code是否为空,当coed为空时则说明当前请求不是认证服务器的回调请求,则重定向URL到认证服务器登陆(使用赛赋IDaaS登陆)
  • 判断authentication  code不为空时,验证Token,并返回用户基本信息、所属角色、访问权限等
  • 从session中获取回调URL,并返回

   demo:
  登陆校验过滤器:web

/**
 * 定义一些页面须要作登陆检查
 *
 * @since 1.0.0
 */
public class LoginInterceptor extends HandlerInterceptorAdapter{
    /**
     * 检查是否已经登陆
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        //获取session中存储的用户信息
        UserBo user = (UserBo) session.getAttribute(Constants.SESSION_USER);
        if(user != null){
            return true;
        }else{
            //若是token不存在,则跳转等登陆页面
            response.sendRedirect(request.getContextPath() + "/login?redirectUrl=" + SpringContextUtils.getRequestUrl(request));
            return false;
        }
    }
}

登陆相关的代码逻辑:spring

/**
 * 登陆
 * @since 1.0.0
 */
@Controller
public class LoginController {
    @Autowired
    private RestTemplate restTemplate;
    @Value("${own.sso.access-token-uri}")
    private String accessTokenUri;
    @Value("${own.sso.verify-uri}")
    private String verifyUri;
    /**
     * 登陆验证(实际登陆调用认证服务器)
     * @date 2020/1/16 18:02
     * @since 1.0.0
     * @param request HttpServletRequest
     * @return org.springframework.web.servlet.ModelAndView
     */
    @RequestMapping("/login")
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response){
        //当前系统登陆成功以后的回调URL
        String redirectUrl = request.getParameter("redirectUrl");
        //当前系统请求认证服务器成功以后返回的Token
        String code = request.getParameter("code");
        //最后重定向的URL
        String resultUrl = "redirect:";
        HttpSession session = request.getSession();
        //1. code为空,则说明当前请求不是认证服务器的回调请求,则重定向URL到认证服务器登陆
        if(StringUtils.isBlank(code)){
            //若是存在回调URL,则将这个URL添加到session
            if(StringUtils.isNoneBlank(redirectUrl)){
                session.setAttribute(Constants.SESSION_LOGIN_REDIRECT_URL,redirectUrl);
            }
            //拼装请求Token的地址
            resultUrl += accessTokenUri;
        }else{
            //2. 验证Token,并返回用户基本信息、所属角色、访问权限等
            SsoResponse verifyResponse = restTemplate.getForObject(verifyUri, SsoResponse.class
                    ,code);
            //若是正常返回
            if(StringUtils.isNoneBlank(verifyResponse.getAccess_token())){
                //2.1 将用户信息存到session
                session.setAttribute(Constants.SESSION_USER,verifyResponse.getUser_info());
                //2.2 将Access Token和Refresh Token写到cookie
                CookieUtils.addCookie(response,Constants.COOKIE_ACCESS_TOKEN, verifyResponse.getAccess_token(),request.getServerName());
                CookieUtils.addCookie(response,Constants.COOKIE_REFRESH_TOKEN, verifyResponse.getRefresh_token(),request.getServerName());
            }
            //3. 从session中获取回调URL,并返回
            redirectUrl = (String) session.getAttribute(Constants.SESSION_LOGIN_REDIRECT_URL);
            session.removeAttribute("redirectUrl");
            if(StringUtils.isNoneBlank(redirectUrl)){
                resultUrl += redirectUrl;
            }else{
                resultUrl += "/user/userIndex";
            }
        }
        return new ModelAndView(resultUrl);
    }
}


faq

其它必要解释说明的信息:segmentfault

  • 应用使用Access Token从IDaaS取得的用户信息。安全

    • IDaaS根据管理后台中配置的子帐号规则返回用户信息。
  • IDaaS返回的用户信息是在应用侧不存在的帐号时,是否提供signup功能
  • OAuth2登陆跳转到IDaaS的方式建议用户2种方案可选:服务器

    • 1.不提供普通的登陆页面,用户输入地址后直接重定向到IDaaS;
    • 2.在原有的登陆页面提供OAuth2的入口按钮【使用赛赋IDaaS登陆】

更多内容

github项目地址:
https://github.com/CipherChin...
CipherIDaaS开源项目QQ群:732326053
公众号:
赛赋公众号.pngcookie

相关文章
相关标签/搜索