当前位置: 代码迷 >> Web前端 >> Weblogic中透过IdentityAsserter实现SSO
  详细解决方案

Weblogic中透过IdentityAsserter实现SSO

热度:124   发布时间:2012-09-04 14:19:30.0
Weblogic中通过IdentityAsserter实现SSO
weblogic8实现SSO的一种简单方案,就是通过IdentityAsserter解决。
步骤一、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 = "&quot;com.huawei.netforce.security.sso.ImepIdentityAsserterProviderImpl&quot;"
/>

<MBeanAttribute 
	Name = "Description" 
	Type = "java.lang.String"
	Writeable = "false" 
	Default = "&quot;ImepIdentityAsserter Identity Assertion Provider&quot;"
/>

<MBeanAttribute 
	Name = "Version" 
	Type = "java.lang.String"
	Writeable = "false" 
	Default = "&quot;1.0&quot;"
/>

<MBeanAttribute 
	Name = "SupportedTypes" 
	Type = "java.lang.String[]"
	Writeable = "false" 
	Default = "new String[] {&quot;ImepToken&quot;}"
/>

<MBeanAttribute 
	Name = "ActiveTypes" 
	Type = "java.lang.String[]"
	Default = "new String[] {&quot;ImepToken&quot;}"
/>
</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);
        }
    }
  相关解决方案