如何實現對接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

相關文章
相關標籤/搜索