一、创建一个新的SSOLogin.jsp
该单点登录的校验服务接口主要由乙方服务商提供,主要分为两步,第一步调用Token授权接口获取Token,然后根据获取的Token调用获取用户信息接口。
Token授权接口(POST请求):https://iam.xxxxx-in.com/idp/oauth2/getToken
获取用户信息接口(GET请求):https://iam.xxxxx-in.com/idp/oauth2/getUserInfo
POST:
//HTTP请求
public static String httpRequestIO(String requestUrl, String param) {
InputStream inputStream = null;
String result = "";
PrintWriter out = null;
try {
URL url = new URL(requestUrl);
HttpURLConnection httpUrlConn =
(HttpURLConnection)url.openConnection();
if (httpUrlConn instanceof HttpsURLConnection) {
((HttpsURLConnection) httpUrlConn).setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname,
SSLSession sslsession) {
return true;
}
});
}
httpUrlConn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
// 发送POST请求必须设置如下两行
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setRequestMethod("POST");
// 获取URLConnection对象对应的输出流
out = new PrintWriter(httpUrlConn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
httpUrlConn.connect();
// 获得返回的输入流
inputStream = httpUrlConn.getInputStream();
int responseCode = httpUrlConn.getResponseCode();
if (responseCode == httpUrlConn.HTTP_OK) {
// 获得输入流,从服务器端获得数据
inputStream = httpUrlConn.getInputStream();
return (changeInputStream(inputStream, "utf-8"));
}
} catch (Exception e) {
result = e.getMessage();
e.printStackTrace();
}
return result;
}
GET:
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
String step = "";
try {
step = "1";
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
step = "2";
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
step = "3";
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko");
step = "4";
// 建立实际的连接
connection.connect();
step = "5";
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + step + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
调用代码(非完整代码):
<%
try{
String sessionId=request.getSession().getId();
//1,getToken 获取授权接口
String code = request.getParameter("code");
response.getWriter().println("code=" + code);
String getToken = httpRequestIO("https://iam.xxxxx-in.com/idp/oauth2/getToken","&client_id=erp&grant_type=authorization_code&code=" + code + "&client_secret=396aba8a638a411cb4b5f09ccff0c35e");
response.getWriter().println("\n getToken=" + getToken);
out.println(getToken.replace("{","").replace("}","").replace("\"","").replace("data:",""));
String[] accesstoken = getToken.replace("{","").replace("}","").replace("\"","").replace("data:","").split(",");
String access_token = "";
for(int i=0; i < accesstoken.length; i++){
//获取access_token
if(accesstoken[i].startsWith("access_token")){
access_token = accesstoken[i].replace("access_token:","");
out.println(accesstoken[i].replace("access_token:",""));
}
response.getWriter().println("accesstoken["+i+"]=" + accesstoken[i]);
}
//2,getUserInfo 获取用户信息接口
String getUserInfo = sendGet("https://iam.xxxxx-in.com/idp/oauth2/getUserInfo","&client_id=erp&access_token=" + access_token);
response.getWriter().println("\n getUserInfo=" + getUserInfo);
//out.println(getUserInfo.replace("{","").replace("}","").replace("\"","").replace("data:",""));
String[] splitstr = getUserInfo.replace("{","").replace("}","").replace("\"","").replace("data:","").split(",");
//用户名
String userName = "";
for(int i=0; i < splitstr.length; i++){
//获取用户名
if(splitstr[i].startsWith("loginName")){
userName = splitstr[i].replace("loginName:","");
out.println(splitstr[i].replace("loginName:",""));
}
response.getWriter().println("splitstr["+i+"]=" + splitstr[i]);
}
//已登录
if(userName.length() > 0 ){
String forwardUrl = "";
WebAppsContext wctx = null;
boolean alreadySet = false;
String langCode = request.getParameter("langCode");
String checkUserResult = "";
if(Utils.isAppsContextAvailable()){
wctx = Utils.getAppsContext();
alreadySet = true;
}else{
wctx = Utils.getAppsContext();
}
if(langCode != null){
wctx.setCurrLang(langCode);
}else{
wctx.setCurrLang(langCode);
langCode="ZHS";
}
java.sql.Connection con = wctx.getJDBCConnection();
//验证用户名
String userNameArray[] = validateUserName(userName, con);
if(userNameArray[0].equals("E")){
throw new Exception(userNameArray[1]);
}
//获取密码
String pwd[] = getPwd(userName, con);
if(pwd[0].equals("E")){
response.getWriter().println("<pre>" + pwd[1]);
throw new RuntimeException("Error "+pwd[1]);
}
UserPwd pUser = new UserPwd(userName,pwd[1]);
forwardUrl = SessionMgr.createAppsSession(pUser, request, response);
//验证用户信息
SessionManager sessionmanager = wctx.getSessionManager();
oracle.apps.fnd.security.SessionManager.AuthStatusCode authstatuscode = sessionmanager.validateLogin(pUser);
if (authstatuscode.VALID == authstatuscode ) {
checkUserResult = "VALID";
} else if ( authstatuscode.INVALID == authstatuscode ){
checkUserResult = "INVALID";
} else if ( authstatuscode.EXPIRED == authstatuscode ){
checkUserResult = "EXPIRED";
}
//wctx.releaseJDBCConnection();
//跳转
if (authstatuscode.toString().equals("EXPIRED")) {
//response.sendRedirect("errorpage.jsp?em="+stringtoUnicode("此账户在")+"ERP"+stringtoUnicode("已过有效期,请联系系统管理员"));
response.getWriter().println("此账户在ERP已过有效期,请联系系统管理员");
}else if (authstatuscode.toString().equals("INVALID")) {
//response.sendRedirect("errorpage.jsp?em="+stringtoUnicode("对不起,您没有")+"ERP"+stringtoUnicode("系统用户权限;如需申请ERP系统用户权限,请联系BP&IT申请"));
response.getWriter().println("对不起,您没有系统用户权限;如需申请ERP系统用户权限,请联系BP&IT申请");
}else {
response.getWriter().println("<pre>" + "<br/>"+forwardUrl + "<br/>"+authstatuscode);
response.sendRedirect(forwardUrl+"&client_id=erp&code=" + code +"&language_code=ZHS&lang_code=ZHS");
}
}else{
//登录失败跳转到SSO登录页面
//String returnUrl= "http://ebsprod-ap1.xxxxx-in.com:8000";
//returnUrl=URLEncoder.encode(returnUrl);
//response.sendRedirect("https://iam.xxxxx-in.com/idp/profile/OAUTH2/Redirect/GLO?returnurl=" + returnUrl);
//response.getWriter().println("登录失败");
response.sendRedirect("https://iam.xxxxx-in.com/idp/themes/default/fail.html");
}
}catch(Exception e){
response.getWriter().println("<pre>" + e.toString());
e.printStackTrace();
//显示错误信息,退出
//response.setHeader("refresh", "3;url=https://iam.xxxxx-in.com/idp/themes/default/fail.html");
response.sendRedirect("https://iam.xxxxx-in.com/idp/themes/default/fail.html");
}
%>
二、修改RF.jsp和OALogout.jsp
JSP存放目录:$OAH_TOP/html,从目录下载RF.jsp和OALogout.jsp两个文件
修改RF.jsp,将登陆网址改为默认跳转到新的SSOLogin.jsp
找到这一段%><jsp:forward page="<%= url.substring(index + 9) %>" /><%
修改为:
oracle.apps.fnd.common.WebAppsContext ctx = Utils.getAppsContext();;
boolean chk = ctx.validateSession(oracle.apps.fnd.framework.webui.OAJSPHelper.getIcxCookie(request, false));
if(!url.contains("sso")){
%><jsp:forward page="<%= url.substring(index + 9) %>" /><%
}else{
String returnUrl= "http://ebsprod-ap1.xxxxx-in.com:8000/OA_HTML/SSOLogin.jsp";
returnUrl=URLEncoder.encode(returnUrl);
response.sendRedirect("https://iam.xxxx-in.com/idp/oauth2/authorize?redirect_uri="+returnUrl+ "&client_id=erp&response_type=code" );
}
修改OALogout.jsp,找到这一段response.sendRedirect(logoutUrl);
修改为:
String returnUrl= "http://ebsprod-ap1.xxxxx-in.com:8000";
returnUrl=URLEncoder.encode(returnUrl);
response.sendRedirect("https://iam.xxxxx-in.com/idp/profile/OAUTH2/Redirect/GLO?redirctToUrl="+returnUrl);
上面分别修改登陆与登出的代码,URLEncoder方法需要引用<%@ page import="java.net.URLEncoder"%>
三、上传与编译
JSP上传路径:$OAH_TOP/html
编译路径:cd $FND_TOP/patch/115/bin
清除.class
rm $COMMON_TOP/_pages/*SSOLogin*
rm $COMMON_TOP/_pages/_OALogout.class
rm $COMMON_TOP/_pages/_RF.class
编译:
$FND_TOP/patch/115/bin/ojspCompile.pl --compile -s OALogout.jsp
$FND_TOP/patch/115/bin/ojspCompile.pl --compile -s SSOLogin.jsp
$FND_TOP/patch/115/bin/ojspCompile.pl --compile -s RF.jsp
编译成功后查看:
$COMMON_TOP/_pages
最后重启服务:
adapcctl.sh stop
adapcctl.sh start
adoacorectl.sh stop
adoacorectl.sh start
该篇仅提供一种实现思路,感兴趣的朋友可参考。