private Response handleBasicAuthFailure() throws OAuthSystemException { OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED) .setError(OAuth2ErrorCodes.INVALID_CLIENT) .setErrorDescription("Client Authentication failed.") .buildJSONMessage(); return Response.status(response.getResponseStatus()) .header(OAuthConstants.HTTP_RESP_HEADER_AUTHENTICATE, EndpointUtil.getRealmInfo()) .entity(response.getBody()) .build(); }
private Response handleSQLError() throws OAuthSystemException { OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_GATEWAY) .setError(OAuth2ErrorCodes.SERVER_ERROR) .setErrorDescription("Service Unavailable Error.") .buildJSONMessage(); return Response.status(response.getResponseStatus()) .header(OAuthConstants.HTTP_RESP_HEADER_AUTHENTICATE, EndpointUtil.getRealmInfo()) .entity(response.getBody()) .build(); }
@RequestMapping("/oAuthLogin") public ModelAndView oAuthLogin(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException { ModelAndView mav = new ModelAndView(); OAuthAuthzRequest oAuthzRequest = new OAuthAuthzRequest(request); String username = oAuthzRequest.getParam(OAuth.OAUTH_USERNAME); String state = oAuthzRequest.getState(); // 生成授权码 String authCode = null; String responseType = oAuthzRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE); // ResponseType仅支持CODE和TOKEN if (responseType.equals(ResponseType.CODE.toString())) { OAuthIssuerImpl oAuthIssuerImpl = new OAuthIssuerImpl(new MD5Generator()); authCode = oAuthIssuerImpl.authorizationCode(); oAuthService.addAuthCode(authCode, username); } // 构建OAuth响应 OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND); // 设置授权码 builder.setCode(authCode); // 获取客户端重定向地址 String redirectURI = oAuthzRequest.getParam(OAuth.OAUTH_REDIRECT_URI); // 构建响应 OAuthResponse response = builder.location(redirectURI).buildBodyMessage(); // 根据OAuthResponse返回ResponseEntity响应 HttpHeaders headers = new HttpHeaders(); try { headers.setLocation(new URI(response.getLocationUri())); // return new ResponseEntity<>(headers, HttpStatus.valueOf(response.getResponseStatus())); } catch (URISyntaxException e) { e.printStackTrace(); } mav.addObject(OAuth.OAUTH_CODE, authCode); mav.addObject(OAuth.OAUTH_STATE, state); mav.setViewName("redirect:" + redirectURI); return mav; }
@POST @Path("/") @Consumes("application/x-www-form-urlencoded") @Produces("application/json") public Response issueAccessToken( @Context HttpServletRequest request, MultivaluedMap<String, String> paramMap) throws OAuthSystemException { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); HttpServletRequestWrapper httpRequest = new OAuthRequestWrapper(request, paramMap); if (log.isDebugEnabled()) { logAccessTokenRequest(httpRequest); } // extract the basic auth credentials if present in the request and use for // authentication. if (request.getHeader(OAuthConstants.HTTP_REQ_HEADER_AUTHZ) != null) { try { String[] clientCredentials = EndpointUtil.extractCredentialsFromAuthzHeader( request.getHeader(OAuthConstants.HTTP_REQ_HEADER_AUTHZ)); // The client MUST NOT use more than one authentication method in each request if (paramMap.containsKey(OAuth.OAUTH_CLIENT_ID) && paramMap.containsKey(OAuth.OAUTH_CLIENT_SECRET)) { return handleBasicAuthFailure(); } // If a client sends an invalid base64 encoded clientid:clientsecret value, it results in // this // array to only contain 1 element. This happens on specific errors though. if (clientCredentials.length != 2) { return handleBasicAuthFailure(); } // add the credentials available in Authorization header to the parameter map paramMap.add(OAuth.OAUTH_CLIENT_ID, clientCredentials[0]); paramMap.add(OAuth.OAUTH_CLIENT_SECRET, clientCredentials[1]); } catch (OAuthClientException e) { // malformed credential string is considered as an auth failure. log.error("Error while extracting credentials from authorization header", e); return handleBasicAuthFailure(); } } try { CarbonOAuthTokenRequest oauthRequest = new CarbonOAuthTokenRequest(httpRequest); // exchange the access token for the authorization grant. OAuth2AccessTokenRespDTO oauth2AccessTokenResp = getAccessToken(oauthRequest); // if there BE has returned an error if (oauth2AccessTokenResp.getErrorMsg() != null) { // if there is an auth failure, HTTP 401 Status Code should be sent back to the client. if (OAuth2ErrorCodes.INVALID_CLIENT.equals(oauth2AccessTokenResp.getErrorCode())) { return handleBasicAuthFailure(); } else if ("sql_error".equals(oauth2AccessTokenResp.getErrorCode())) { return handleSQLError(); } else if (OAuth2ErrorCodes.SERVER_ERROR.equals(oauth2AccessTokenResp.getErrorCode())) { return handleServerError(); } else { // Otherwise send back HTTP 400 Status Code OAuthResponse.OAuthErrorResponseBuilder oAuthErrorResponseBuilder = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST) .setError(oauth2AccessTokenResp.getErrorCode()) .setErrorDescription(oauth2AccessTokenResp.getErrorMsg()); OAuthResponse response = oAuthErrorResponseBuilder.buildJSONMessage(); ResponseHeader[] headers = oauth2AccessTokenResp.getResponseHeaders(); ResponseBuilder respBuilder = Response.status(response.getResponseStatus()); if (headers != null && headers.length > 0) { for (int i = 0; i < headers.length; i++) { if (headers[i] != null) { respBuilder.header(headers[i].getKey(), headers[i].getValue()); } } } return respBuilder.entity(response.getBody()).build(); } } else { OAuthTokenResponseBuilder oAuthRespBuilder = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK) .setAccessToken(oauth2AccessTokenResp.getAccessToken()) .setRefreshToken(oauth2AccessTokenResp.getRefreshToken()) .setExpiresIn(Long.toString(oauth2AccessTokenResp.getExpiresIn())) .setTokenType(BEARER); oAuthRespBuilder.setScope(oauth2AccessTokenResp.getAuthorizedScopes()); // OpenID Connect ID token if (oauth2AccessTokenResp.getIDToken() != null) { oAuthRespBuilder.setParam(OAuthConstants.ID_TOKEN, oauth2AccessTokenResp.getIDToken()); } OAuthResponse response = oAuthRespBuilder.buildJSONMessage(); ResponseHeader[] headers = oauth2AccessTokenResp.getResponseHeaders(); ResponseBuilder respBuilder = Response.status(response.getResponseStatus()) .header( OAuthConstants.HTTP_RESP_HEADER_CACHE_CONTROL, OAuthConstants.HTTP_RESP_HEADER_VAL_CACHE_CONTROL_NO_STORE) .header( OAuthConstants.HTTP_RESP_HEADER_PRAGMA, OAuthConstants.HTTP_RESP_HEADER_VAL_PRAGMA_NO_CACHE); if (headers != null && headers.length > 0) { for (int i = 0; i < headers.length; i++) { if (headers[i] != null) { respBuilder.header(headers[i].getKey(), headers[i].getValue()); } } } return respBuilder.entity(response.getBody()).build(); } } catch (OAuthProblemException e) { log.error("Error while creating the Carbon OAuth token request", e); OAuthResponse res = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST) .error(e) .buildJSONMessage(); return Response.status(res.getResponseStatus()).entity(res.getBody()).build(); } } finally { PrivilegedCarbonContext.endTenantFlow(); } }
/** * 用户访问客户端,后者将前者导向认证服务器。此为认证服务器,判断是否授权 * * @param request HttpServletRequest * @return 重定向URI redirectURI & 授权码 authCode & 当前状态 state * @throws OAuthSystemException * @throws OAuthProblemException */ @RequestMapping("/authorize") public ModelAndView Authorize(HttpServletRequest request) throws OAuthSystemException, OAuthProblemException { ModelAndView mav = new ModelAndView(); /* String username, String webKey, String scope, String state,String diasplay 构建OAuth请求 */ OAuthAuthzRequest oAuthzRequest = new OAuthAuthzRequest(request); // 获取OAuth客户端Id String clientId = oAuthzRequest.getClientId(); // 校验客户端Id是否正确 if (!oAuthService.checkClientId(clientId)) { OAuthResponse oAuthResponse = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST) .setError(OAuthError.TokenResponse.INVALID_CLIENT) .setErrorDescription("无效的客户端Id") .buildJSONMessage(); mav.addObject(OAuth2Constants.OAUTH_AUTHORIZE_FAILED_KEY, "无效的客户端Id"); mav.setViewName("forward:/oauth2/authorizefailed"); return mav; // return new ResponseEntity(oAuthResponse.getBody(), // HttpStatus.valueOf(oAuthResponse.getResponseStatus())); } String username = "******"; String state = oAuthzRequest.getState(); // 生成授权码 String authCode = null; String responseType = oAuthzRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE); // ResponseType仅支持CODE和TOKEN if (responseType.equals(ResponseType.CODE.toString())) { OAuthIssuerImpl oAuthIssuerImpl = new OAuthIssuerImpl(new MD5Generator()); authCode = oAuthIssuerImpl.authorizationCode(); oAuthService.addAuthCode(authCode, username); } // 构建OAuth响应 OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND); // 设置授权码 builder.setCode(authCode); // 获取客户端重定向地址 String redirectURI = oAuthzRequest.getParam(OAuth.OAUTH_REDIRECT_URI); // 构建响应 OAuthResponse response = builder.location(redirectURI).buildBodyMessage(); // 根据OAuthResponse返回ResponseEntity响应 HttpHeaders headers = new HttpHeaders(); try { headers.setLocation(new URI(response.getLocationUri())); // return new ResponseEntity<>(headers, HttpStatus.valueOf(response.getResponseStatus())); } catch (URISyntaxException e) { e.printStackTrace(); } mav.addObject(OAuth.OAUTH_CODE, authCode); mav.addObject(OAuth.OAUTH_STATE, state); mav.setViewName("redirect:" + redirectURI); return mav; }