WSO2 Identity Server - Oauth 2.0 - Java

时间:2015-09-01 17:27:32

标签: oauth-2.0 wso2 identity logoff

我为Oauth2身份验证流程编写了一个基于Java的签名例程(令牌撤销)。请参阅下面[here]手册中cURL协议说明的代码实现。程序代码编译并在没有错误消息的情况下工作,但在注销后,用户帐户仍然在WSO2仪表板查询下保持连接状态。

请参阅下面触发注销功能的Servlet类:

class SignoffServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {

                try{
       String accessToken = (String) req.getSession().getAttribute("access_token"); 
       System.out.println("Start Logoff processing for revoke of the token: " + accessToken);
           URL url = new URL (Oauth2Server + "/oauth2/revoke?token="+accessToken); 
       HttpURLConnection connection = (HttpURLConnection) url.openConnection();
       // new encode with Apache codec (for Java8 use native lib) 
       String userCredentials = clientId + ":" + clientSecret;
       String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
       connection.setRequestProperty ("Authorization", basicAuth);
       connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");    
       connection.addRequestProperty("token", accessToken); 
       connection.addRequestProperty("token_type_hint", "access_token");
       //connection.setRequestProperty("token", accessToken); 
       // connection.setRequestProperty("token_type_hint", "access_token");
                   connection.setRequestMethod("POST");
                   connection.setDoOutput(true);
                   InputStream content = (InputStream)connection.getInputStream();
                   BufferedReader in   = 
                     new BufferedReader (new InputStreamReader (content));
                     String line;
                     while ((line = in.readLine()) != null) {
                         System.out.println(line);
                         System.out.println("Logoff finished sucessfully");
                         }
                    } catch(Exception e) {
                      System.out.println("Logoff failed, error cause: " + e.toString());
                      e.printStackTrace();
                    }
    System.out.println("Logoff finished sucessfully");
    // return the json of the user's basic info
    String html_header = "<html><body>"; 
    String myjson = "<br>Logoff completed sucessfully"; 
    myjson += "<br><br><b><a href='./index.html'>Back to login page</a></b><br>";
    String html_footer = "</body></html>";  
    String mypage = html_header + myjson + html_footer; 
    resp.setContentType("text/html");
    resp.getWriter().println(myjson);
}   

}

欢迎使用有关在Java代码中更改内容以激活Oauth 2.0的签名功能的建议。

感谢您详细解释Oauth2中授权和身份验证之间的区别。请参阅下面的代码,该代码可以撤消有效的Oauth2令牌:

class SignoffServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {

    String outputl = "";        
                try{
       String accessToken = (String) req.getSession().getAttribute("access_token"); 
           // testing .. inhibu acivate this line:  // revoke accessToken = "abc";             
       System.out.println("Start Logoff processing for revoke of the token: " + accessToken);
           // URL url = new URL (Oauth2Server + "/oauth2/revoke?token="+accessToken); 
           // URL url = new URL (Oauth2Server + "/oauth2endpoints/revoke");
       URL url = new URL (Oauth2Server + "/oauth2/revoke");
       HttpURLConnection connection = (HttpURLConnection) url.openConnection();
       connection.setRequestMethod("POST");
       connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
       // new encode with Apache codec (for Java8 use native lib) 
       String userCredentials = clientId + ":" + clientSecret;
       String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
       basicAuth = basicAuth.replace("\\r", "");
       basicAuth = basicAuth.replace("\\n", "");
                   connection.setRequestProperty ("Authorization", basicAuth);
       connection.setUseCaches(false);
       connection.setDoInput(true);
       connection.setDoOutput(true);
       // send data     
           // String str =  "{\"token\": \"" + accessToken + "\",\"token_type_hint\":\"access_token\"}";
       // example of JSON string  "{\"x\": \"val1\",\"y\":\"val2\"}";
       //byte[] outputInBytes = str.getBytes("UTF-8");
       //OutputStream os = connection.getOutputStream();
       //os.write( outputInBytes );    
       // os.close();
       //send request 
       DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); 
       wr.writeBytes("token=" + accessToken); 
       wr.flush(); 
       wr.close(); 
        // end of new method 
                   InputStream content = (InputStream)connection.getInputStream();
                   BufferedReader in   = 
                     new BufferedReader (new InputStreamReader (content));
                     String line;
                     while ((line = in.readLine()) != null) {
                         // System.out.println(line); // for debug only 
             outputl += line; 
                         }
                    } catch(Exception e) {
                      System.out.println("Logoff failed, error cause: " + e.toString());
                      e.printStackTrace();
                    }
    System.out.println("Logoff finished successfully");
    // return the json of the user's basic info
    // customized Apache HTTP GET with header - Claude, 27 August 2015 reading user information 
    // ===============================================================================================
                String tokeninfo = ""; 
    String infourl = Oauth2Server + "/oauth2/userinfo?schema=openid";
                StringBuilder infobody = new StringBuilder();
                DefaultHttpClient infohttpclient = new DefaultHttpClient(); // create new httpClient 
                HttpGet infohttpGet = new HttpGet(infourl); // create new httpGet object
                // get some info about the user with the access token
    String currentToken = (String) req.getSession().getAttribute("access_token");
                String bearer = "Bearer " + currentToken.toString(); 
        infohttpGet.setHeader("Authorization", bearer);
    try {
           HttpResponse response = infohttpclient.execute(infohttpGet); // execute httpGet
           StatusLine statusLine = response.getStatusLine();
                   int statusCode = statusLine.getStatusCode();
                   if (statusCode == HttpStatus.SC_OK) {
                       System.out.println(statusLine);
                       infobody.append(statusLine + "\n");
                       HttpEntity e = response.getEntity();
                       String entity = EntityUtils.toString(e);
                       infobody.append(entity);
                       } else {
                              infobody.append(statusLine + "\n");
                              // System.out.println(statusLine);
                              }
                    } catch (ClientProtocolException e) {
                      e.printStackTrace();
                    } catch (IOException e) {
                      e.printStackTrace();
                    } finally {
                      tokeninfo = infobody.toString();  
                      infohttpGet.releaseConnection(); // stop connection
                    }
    // User info lookup is done fetching current log status of the token 
    if (tokeninfo.startsWith("HTTP/1.1 400 Bad Request")) { 
        tokeninfo = "Token " + currentToken + " was revoked";               
        };  
    String html_header = "<html><body>"; 
    String myjson = "<br>Logoff completed successfully"; 
    myjson += "<br>Current Userinfo and Token Status";
    myjson += "<br>" + tokeninfo + "<br>"; 
    myjson += "<br><br><b><a href='./index.html'>Back to login page</a></b><br>";
    String html_footer = "</body></html>";  
    String mypage = html_header + myjson + html_footer; 
    resp.setContentType("text/html");
    resp.getWriter().println(myjson);
    // to print signoff screen for debug purpose
    // resp.getWriter().println(outputl);
}   

}

1 个答案:

答案 0 :(得分:2)

上面提到了撤销访问令牌的方法。从OAuth2授权服务器撤销和签署访问令牌是两个不同的过程。举个例子;在Facebook中,您可以撤消为不同应用程序提供的访问令牌。但这并不意味着您已从FB或您已登录的任何其他应用程序注销。

OAuth2不是身份验证机制。它是授权框架。它不包含从授权服务器注销的标准方法。但是,您可以使用一些自定义方式从WSO2IS中签出(终止WSO2IS中的SSO会话),这可以使用。但是,必须通过调用以下url使用最终用户的浏览器(不使用反向通道)来完成。请查看this的最后一部分了解更多详情

namespace detail {
    template <typename T>
    struct is_foo : std::false_type{};
    template <typename T, typename A>
    struct is_foo<Foo<T,A>> : std::true_type{};
}
template <typename T>
using is_foo = detail::is_foo<typename std::decay<T>::type>;

template <typename T, typename A>
int bar(const Foo<T,A> &x) { return 0; }

template <typename T, 
   typename = typename std::enable_if<!is_foo<T>::value>::type>
auto bar(const T &x)
 -> decltype(bar(Foo<T>{})){    
    Foo<T> b{};
    return bar(b);    
}