moss版本:2007
exchange版本:2007
开发工具:vs2008
最近一直在做基于moss的应用开发,有这样一个需求。
因为客户同时上了exchang2007,想在moss网站上显示exchange邮箱信息,这方面可以通过moss自带的owa webpart来配置实现,但是客户又说了既然登录了moss,就不要登录exchange了吧(因为自带的owa webpart还需要用户输入用户名和密码)。那就需要sso了,这里我们就借助moss的sso。moss的sso只是帮助用户存储应用和应用对应的用户名/密码,例如存储了需要sso的应用包括gmai,163mail,应用名/用户名/密码包括gmail/zhangsan/zhangsan,gmail/lisi/lisi/,163mail/zhangsan/zhangsan,163mail/lisi/lisi,然后张三需要登录gmail的时候就会从应用gmail下面查找有无zhangsan的信息,如果有就取出来存储的张三的gmail的用户名和密码,然后我们自己post到gmail去,实现单点登录。至于具体的配置我就不详述了,网上很多,可以参考
http://blog.csdn.net/RainyLin/archive/2009/05/20/4204491.aspx http://microsoft.cnfan.net/sps/3333.html 我这里给出的是一些代码,首先是我们post数据的html页面。思路是我们通过一个html页面post数据到exchange的
http://mail.moss.com/owa/auth/owaauth.dll,因为你会发现owa/auth下面的logon.aspx页面就是post数据到
owaauth.dll去处理的,所以我们也post到这个dll处理。同时注意这个文件的输入框的name要和他的logon.aspx页面一致。

owaredirect.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;CHARSET=utf-8">
<meta name="Robots" content="NOINDEX, NOFOLLOW">
<title>Microsoft Exchange -Outlook Web Access</title>
<script type="text/javascript">
<!--
function getParameter(queryString, parameterName) {
//alert("queryString:"+queryString);
//alert("parameterName:"+parameterName);
var parmeterName = parameterName + "=";
if (queryString.length > 0) {
begin = queryString.indexOf(parameterName);
if (begin != -1) {
begin += parameterName.length + 1;
end = queryString.indexOf("&", begin);
if (end == -1) {
end = queryString.length;
}
return unescape(queryString.substring(begin, end));
}
return "null";
}
}
function SetParams() {
var queryString = window.location.search.substring(1);
logonForm.username.value = getParameter(queryString, "l");
logonForm.password.value = getParameter(queryString, "p");
//logonForm.username.value="administrator";
//logonForm.password.value="cds323458@2008";
//alert(logonForm.username.value+"\t"+logonForm.password.value);
window.document.logonForm.submit();
}
-->
</script>
</head>
<body onload="SetParams();">
please wait




<form action="http://mail.moss.com/owa/auth/owaauth.dll" method="post" name="logonForm"
autocomplete="off">
<input type="hidden" name="destination" value="http://mail.ucs.cds.gfdx.mtn/owa/">
<input type="hidden" name="flags" value="0">
<input type="hidden" name="forcedownlevel" value="0">
<input type="hidden" id="rdoPblc" name="trusted" value="0">
<input id="username" name="username" type="hidden">
<input id="password" name="password" type="hidden">
</form>
</body>
</html>
这个html页面是通过iframe被嵌入到一个ascx中的,ascx文件代码如下

LoginMail.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="LoginMail.ascx.cs" Inherits="Kimbanx.UCS.SSO.Exchange.LoginMail" %>
<iframe runat="server" frameborder="0" class="ExchangeSSOframe" id="exchangeiframe" src=""></iframe>

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Portal;
using System.Runtime.InteropServices;
using Microsoft.SharePoint.Portal.SingleSignon;
namespace Kimbanx.UCS.SSO.Exchange
{
public partial class LoginMail : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
string strSSOLogonFormUrl = SingleSignonLocator.GetCredentialEntryUrl("Exchange2007");
try
{
//writer.Write("if your login fails, please <a href=\"" + strSSOLogonFormUrl + "\">Update your credentials</a> with your new password.<br/>");
string[] rgGetCredentialData = null;
Credentials.GetCredentials(1, "Exchange2007", ref rgGetCredentialData);
string src = SPContext.Current.Site.Url + "/_layouts/owaredirect.html?l=" + rgGetCredentialData[0] + "&p=" + rgGetCredentialData[1];
//writer.Write("<iframe frameborder=\"0\" class =\"ExchangeSSOframe\" src=\"" + src + "\" />");
this.exchangeiframe.Attributes.Add("src", src);
}
catch (SingleSignonException ssoex)
{
if (SSOReturnCodes.SSO_E_CREDS_NOT_FOUND == ssoex.LastErrorCode)
{
Context.Response.Redirect(strSSOLogonFormUrl);
}
else
{
LiteralControl liter = new LiteralControl("请将后面的错误信息提交给管理员:"+ssoex .Message );
this.Controls.Add(liter);
}
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
SSOCanaryChecker.AddCanary(Page);
}
}
} 后台的代码如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构