weblogic8实现SSO的一种简单方案,就是通过IdentityAsserter解决。
步骤一、SSO目标配置
步骤二、创建Identity Assertion Provider
1、产生MDF:ImepIdentityAsserter.xml
java -DcreateStubs="true" weblogic.management.commo.WebLogicMBeanMaker -MDF ImepIdentityAsserter.xml -files d:\src
2、创建提供程序实现
3、MJF打包
java weblogic.management.commo.WebLogicMBeanMaker -MJF ImepIdentityProvider.jar -files d:\src
4、服务端配置
把这个提供程序(ImepIdentityProvider.jar)复制到WL_HOME/server/lib/mbeantypes目录下,然后重新启动服务器。启动管理控制台,并导航到Security/myrealm Providers/Authentication节点。在可用验证器和身份确认器的列表中,应该可以找到“Configure a new ImepIdentityAsserter...”选项。选择这个选项并点击Create,就可以配置身份确认器了。在接下来的选项卡中,您将会注意到,支持的令牌类型被设置为ImepToken和对于ImepToken是活动的令牌。现在,必须重新启动服务器,从而使修改生效。
步骤三、测试
1、URLConnection测试
2、SSO源测试
由于IdentityAsserter需要客户端提供令牌,故在请求SSO目标应用时,需要在cookie中增加ImepToken属性
SSO目标在接收token并redirect的servlet代码片段为:
步骤一、SSO目标配置
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.do</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.htm</url-pattern>
<url-pattern>*.doc</url-pattern>
<url-pattern>*.xls</url-pattern>
<url-pattern>*.xlsx</url-pattern>
<url-pattern>*.zip</url-pattern>
<url-pattern>*.rar</url-pattern>
<url-pattern>*.jpg</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>secrole</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>myrealm</realm-name>
</login-config>
<security-role>
<role-name>secrole</role-name>
</security-role>
步骤二、创建Identity Assertion Provider
1、产生MDF:ImepIdentityAsserter.xml
<?xml version="1.0" ?>
<!DOCTYPE MBeanType SYSTEM "commo.dtd">
<MBeanType
Name = "ImepIdentityAsserter"
DisplayName = "ImepIdentityAsserter"
Package = "com.huawei.netforce.security.sso"
Extends = "weblogic.management.security.authentication.IdentityAsserter"
PersistPolicy = "OnUpdate"
>
<MBeanAttribute
Name = "ProviderClassName"
Type = "java.lang.String"
Writeable = "false"
Default = ""com.huawei.netforce.security.sso.ImepIdentityAsserterProviderImpl""
/>
<MBeanAttribute
Name = "Description"
Type = "java.lang.String"
Writeable = "false"
Default = ""ImepIdentityAsserter Identity Assertion Provider""
/>
<MBeanAttribute
Name = "Version"
Type = "java.lang.String"
Writeable = "false"
Default = ""1.0""
/>
<MBeanAttribute
Name = "SupportedTypes"
Type = "java.lang.String[]"
Writeable = "false"
Default = "new String[] {"ImepToken"}"
/>
<MBeanAttribute
Name = "ActiveTypes"
Type = "java.lang.String[]"
Default = "new String[] {"ImepToken"}"
/>
</MBeanType>
java -DcreateStubs="true" weblogic.management.commo.WebLogicMBeanMaker -MDF ImepIdentityAsserter.xml -files d:\src
2、创建提供程序实现
import java.io.PrintStream;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AppConfigurationEntry;
import weblogic.management.security.ProviderMBean;
import weblogic.security.spi.*;
public class ImepIdentityAsserterProviderImpl
implements AuthenticationProvider, IdentityAsserter
{
private static final String TOKEN_TYPE = "ImepToken";
private static final String TOKEN_PREFIX = "username=";
private String description;
public ImepIdentityAsserterProviderImpl()
{
}
public AppConfigurationEntry getAssertionModuleConfiguration()
{
return null;
}
public IdentityAsserter getIdentityAsserter()
{
return this;
}
public AppConfigurationEntry getLoginModuleConfiguration()
{
return null;
}
public PrincipalValidator getPrincipalValidator()
{
return null;
}
public String getDescription()
{
return description;
}
public void initialize(ProviderMBean mbean, SecurityServices services)
{
System.out.println("ImepIdentityAsserterProviderImpl.initialize");
ImepIdentityAsserterMBean myMBean = (ImepIdentityAsserterMBean)mbean;
description = myMBean.getDescription() + "\n" + myMBean.getVersion();
}
public void shutdown()
{
}
public CallbackHandler assertIdentity(String type, Object token)
throws IdentityAssertionException
{
if(!"ImepToken".equals(type))
{
String error = "ImepIdentityAsserterProviderImpl received unknown token type \"" + type + "\"." + " Expected " + "ImepToken";
throw new IdentityAssertionException(error);
}
if(!(token instanceof byte[]))
{
String error = "ImepIdentityAsserterProviderImpl received unknown token class \"" + token.getClass() + "\"." + " Expected a byte[].";
throw new IdentityAssertionException(error);
}
byte tokenBytes[] = (byte[])token;
if(tokenBytes == null || tokenBytes.length < 1)
{
String error = "ImepIdentityAsserterProviderImpl received empty token byte array";
throw new IdentityAssertionException(error);
}
String tokenStr = new String(tokenBytes);
if(!tokenStr.startsWith("username="))
{
String error = "ImepIdentityAsserterProviderImpl received unknown token string \"" + type + "\"." + " Expected " + "username=" + "username";
throw new IdentityAssertionException(error);
} else
{
String userName = tokenStr.substring("username=".length());
return new ImepCallbackHandlerImpl(userName);
}
}
}
import java.io.IOException;
import javax.security.auth.callback.*;
public class ImepCallbackHandlerImpl
implements CallbackHandler
{
private String userName;
public ImepCallbackHandlerImpl(String aUserName)
{
userName = aUserName;
}
public void handle(Callback callbacks[])
throws IOException, UnsupportedCallbackException
{
for(int i = 0; i < callbacks.length; i++)
{
Callback callback = callbacks[i];
if(!(callback instanceof NameCallback))
throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
NameCallback nameCallback = (NameCallback)callback;
nameCallback.setName(userName);
}
}
}
3、MJF打包
java weblogic.management.commo.WebLogicMBeanMaker -MJF ImepIdentityProvider.jar -files d:\src
4、服务端配置
把这个提供程序(ImepIdentityProvider.jar)复制到WL_HOME/server/lib/mbeantypes目录下,然后重新启动服务器。启动管理控制台,并导航到Security/myrealm Providers/Authentication节点。在可用验证器和身份确认器的列表中,应该可以找到“Configure a new ImepIdentityAsserter...”选项。选择这个选项并点击Create,就可以配置身份确认器了。在接下来的选项卡中,您将会注意到,支持的令牌类型被设置为ImepToken和对于ImepToken是活动的令牌。现在,必须重新启动服务器,从而使修改生效。
步骤三、测试
1、URLConnection测试
try
{
//test账户需要在myrealm中进行配置
String token = "username=test";
//是否需要编码可在控制台配置时取消,默认为BASE64编码
BASE64Encoder encoder = new BASE64Encoder();
String encodedToken = encoder.encodeBuffer(token.getBytes());
URL url = new URL("http://localhost:7001/app/index.jsp");
URLConnection connection = url.openConnection();
connection.setRequestProperty("ImepToken",encodedToken);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = "";
while((line = in.readLine()) != null)
{
System.out.println(line);
}
}
catch(Exception e)
{
e.printStackTrace();
}
2、SSO源测试
由于IdentityAsserter需要客户端提供令牌,故在请求SSO目标应用时,需要在cookie中增加ImepToken属性
SSO目标在接收token并redirect的servlet代码片段为:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String tokenValue = request.getParameter("token");
String redirect = request.getParameter("redirect");
if(StringUtils.isNotEmpty(tokenValue))
{
//IdentityAsserterProvider从cookie或者header中取token
Cookie cookie = new Cookie("ImepToken", tokenValue);
response.addCookie(cookie);
response.setHeader("ImepToken",tokenValue);
//添加P3P策略主要解决iframe集成时浏览器阻止跨域cookie
response.setHeader("P3P","CP=CAO PSA OUR");
response.sendRedirect(redirect);
}
}