增加SharePoint2010修改域密码功能
前提
SharePoint2010的用户基于AD的,因此修改密码是修改了AD的密码,当然也可以修改本机密码(非域的密码)。这里我们讨论修改域密码。我们修改需要用到sharepoint的弹出对话框的模式,以下为几个对话框函数:
? SP.UI.ModalDialog.showModalDialog:弹出对话框
? SP.UI.Status.addStstus:自定义状态栏信息
? SP.UI.Notify.addNotification:自定义消息通知
配置开发
1. 使用sharepoint designer2010打开对应站点http://moss:8002 ,找到v4.master如下图:
2. 打开编辑v4.master,如下图:
添加JS代码:
采用自定义通知栏模式
<script language="javascript"
type="text/javascript">
function
portal_openModalDialog()
{
var options =
SP.UI.$create_DialogOptions();
options.width = 500;
options.height = 250;
options.url
=
"/_layouts/TCL.EG.ModifyPasswd/ModifyPasswd.aspx";
options.dialogReturnValueCallback = Function.createDelegate(null,
portal_modalDialogClosedCallback);
SP.UI.ModalDialog.showModalDialog(options);
}
//关闭函数
function
portal_modalDialogClosedCallback(result, value)
{
if (value == "1")
{
//自定义通知栏
SP.UI.Notify.addNotification("恭喜!修改成功!");
}
else if (value == "0")
{
//自定义通知栏
SP.UI.Notify.addNotification("修改失败,请联系管理员!");
}
}
//关闭函数
function closeDialog()
{
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel,
3);
}
</script>
?
采用自定义状态栏模式
<script
language="javascript" type="text/javascript">
function
portal_openModalDialog()
{
var options =
SP.UI.$create_DialogOptions();
options.width = 500;
options.height = 250;
options.url
=
"/_layouts/TCL.EG.ModifyPasswd/ModifyPasswd.aspx";
options.dialogReturnValueCallback = Function.createDelegate(null,
portal_modalDialogClosedCallback);
SP.UI.ModalDialog.showModalDialog(options);
}
//关闭函数
function
portal_modalDialogClosedCallback(result, value)
{
if (value == "1")
{
//自定义状态栏
this.statusId = SP.UI.Status.addStatus
("恭喜!修改成功!",“修改密码成功,请重新登录!”,true);
}
else if (value == "0")
{
//自定义通知栏
this.statusId
=SP.UI.Status.addStatus
("修改失败!",“修改失败,请联系管理员!”,true);
}
SP.UI.Status.setStatusPriColor(this.statusId,
"Green");
setTimeout(RemoveStatus, 6000);
}
function
RemoveStatus() {
SP.UI.Status.removeStatus(this.statusId);
}
//关闭函数
function
closeDialog()
{
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel,
3);
}
</script>
加入母版页面中,签入即可,如下图:
3. 使用VS2010开发添加sharepoint空白项目,如下图:
4. 添加空元素,如下图:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="{BC477D9E-365A-47BD-AB2B-BE06FA44628D}"
Title="修改密码"
Description="此处修改的是域里面的密码"
Sequence="1000"
Location="Microsoft.SharePoint.StandardMenu"
GroupId="PersonalActions"
ImageUrl="~sitecollection/_layouts/images/menulistsettings.gif">
<UrlAction Url="javascript:portal_openModalDialog();"/>
</CustomAction>
</Elements>
5. 添加修改密码的页面,页面代码部分如下:
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@
Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@
Register TagPrefix="SharePoint"
Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities"
Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint,
Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
%>
<%@ Register TagPrefix="asp" Namespace="System.Web.UI"
Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" %>
<%@ Import
Namespace="Microsoft.SharePoint" %>
<%@ Assembly
Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#"
AutoEventWireup="true" CodeBehind="ModifyPasswd.aspx.cs"
Inherits="TCL.EG.ModifyPasswd.Layouts.TCL.EG.ModifyPasswd.ModifyPasswd"
DynamicMasterPageFile="~masterurl/default.master" %>
<asp:Content
ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead"
runat="server">
</asp:Content>
<asp:Content ID="Main"
ContentPlaceHolderID="PlaceHolderMain" runat="server">
<table cellpadding="0" cellspacing="0"
border="0">
<tr>
<td>
旧密码:
</td>
<td>
<asp:TextBox ID="txtOldPwd" runat="server"
TextMode="Password"></asp:TextBox>
</td>
</tr>
<tr>
<td>
新密码:
</td>
<td>
<asp:TextBox ID="txtNewPwd" runat="server"
TextMode="Password"></asp:TextBox>
</td>
</tr>
<tr>
<td>
确认密码:
</td>
<td>
<asp:TextBox ID="txtConfirmPwd" runat="server"
TextMode="Password"></asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:Button ID="btnUpdate" runat="server" Text="保存" OnClick="btnUpdate_Click"
/>
</td>
<td>
<asp:Button ID="btnCancel" runat="server" Text="取消"
OnClientClick="closeDialog()"
/>
</td>
</tr>
<tr>
<td
colspan="2">
<font color="red"><asp:Label ID="Label_Title" runat="server"
></asp:Label></font>
</td>
</tr>
</table>
</asp:Content>
<asp:Content ID="PageTitle"
ContentPlaceHolderID="PlaceHolderPageTitle"
runat="server">
修改密码
</asp:Content>
<asp:Content ID="PageTitleInTitleArea"
ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"
runat="server">
我的应用程序页
</asp:Content>
6、后台代码.cs部分,如下:
using System;
using
Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using
System.DirectoryServices.AccountManagement;
using
System.Security.Principal;
using System.Runtime.InteropServices;
using
System.ComponentModel;
using System.DirectoryServices;
namespace
TCL.EG.ModifyPasswd.Layouts.TCL.EG.ModifyPasswd
{
public partial class ModifyPasswd : LayoutsPageBase
{
#region//变量
///
<summary>
///
///
</summary>
private string
_userName;
///
///
</summary>
private
PrincipalContext
_principalContext;
private string
newPasswd = string.Empty;
private
string confirmPasswd =
string.Empty;
private string
oldPasswd = string.Empty;
#endregion
#region//事件
protected void
Page_Load(object sender, EventArgs
e)
{
if
(!Page.IsPostBack)
{
}
}
///
<summary>
///
更新密码
///
</summary>
/// <param
name="sender"></param>
/// <param
name="e"></param>
protected void btnUpdate_Click(object sender, EventArgs
e)
{
if
(SPContext.Current !=
null)
{
//登录名
_userName =
SPContext.Current.Web.CurrentUser.LoginName;
//
if (_userName.ToLower() ==
"sharepoint\\system")
{
_userName =
"contoso\\mossadmin";
}
//旧密码不允许为空
//修改密码
newPasswd =
this.txtNewPwd.Text.Trim();
confirmPasswd =
this.txtConfirmPwd.Text.Trim();
oldPasswd =
txtOldPwd.Text.Trim();
//
if
(string.IsNullOrEmpty(oldPasswd))
{
this.Label_Title.Text =
"请输入旧密码!";
return;
}
if
(string.IsNullOrEmpty(newPasswd))
{
this.Label_Title.Text =
"请输入新密码!";
return;
}
if
(string.IsNullOrEmpty(confirmPasswd))
{
this.Label_Title.Text =
"请输入确认密码!";
return;
}
//判断2次密码是否一致。
if (newPasswd !=
confirmPasswd)
{
this.Label_Title.Text =
"新密码与确认密码不一致!";
return;
}
//_userName
if
(!string.IsNullOrEmpty(_userName))
{
//登录名为contoso\\mossadmin
try
{
//检查原始密码是否正确
bool isOK = CheckUser(ValidType.Domain, _userName,
oldPasswd);
//如果正确
if
(!isOK)
{
this.Label_Title.Text =
"旧密码输入错误!";
return;
}
else
{
//更改密码
bool isreult = UpdateMyPassword(newPasswd,
oldPasswd);
//
if
(isreult)
{
//提示信息
Response.Write(
"<script
type=\"text/javascript\">window.frameElement.commonModalDialogClose(1,
1);</script>");
}
}
}
catch (Exception
ex)
{
this.Label_Title.Text =
ex.Message;
}
}
}
}
#endregion
#region//方法
#region//修改密码
///
<summary>
///
修改密码
///
</summary>
/// <param
name="newUserPasswd">新密码</param>
/// <param
name="oldUserPasswd">原始密码</param>
///
<returns>返回结果是否成功</returns>
private bool UpdateMyPassword(string newUserPasswd,string
oldUserPasswd)
{
//返回ok
bool _result =
false;
try
{
Impersonator Imp = new
Impersonator();
//开始
Imp.BeginImpersonation();
//
using (var context = new
PrincipalContext(ContextType.Domain))
{
using (UserPrincipal usr =
UserPrincipal.FindByIdentity(
context,
IdentityType.SamAccountName,
Microsoft.SharePoint.SPContext.Current.Web.CurrentUser.LoginName))
{
usr.UserCannotChangePassword =
true;
usr.ChangePassword(oldUserPasswd,
newUserPasswd);
}
}
//修改
if
(Imp.IsImpersonated)
{
Imp.StopImpersonation();
//Ok
_result =
true;
}
else
{
//fail
_result =
false;
}
}
catch(Exception
ex)
{
this.Label_Title.Text =
ex.Message;
_result =
false;
}
//return
return _result;
}
#endregion
#region//验证原始密码是否正确
///
<summary>
///
验证原始密码是否正确
///
</summary>
///
<param name="validType">验证类型</param>
/// <param
name="UserName">登录名</param>
/// <param
name="PassWord">登录密码</param>
///
<returns>返回是否成功的标识</returns>
public Boolean
CheckUser(ValidType validType, String UserName, String PassWord)
{
try
{
String[] UserArray = UserName.Split(new char[] { ‘\\‘ }); //UserName 組合為
Domain\Account 或 MachineName\Account
InitPC(validType, UserArray[0]);
Boolean isValid = _principalContext.ValidateCredentials(UserArray[1],
PassWord);
return isValid;
}
catch
(Exception ex)
{
this.Label_Title.Text =
ex.Message;
return false;
}
}
#endregion
#region//PrincipalContext初始化
///
<summary>
///
PrincipalContext初始化
///
</summary>
///
<param name="validType">验证类型</param>
/// <param
name="LDAPName">应用程序</param>
private void InitPC(ValidType
validType, String LDAPName)
{
//PrincipalContext pc = null;
int
typeNum =
(int)validType;
switch
(typeNum)
{
case
1:
_principalContext = new PrincipalContext(ContextType.Domain,
LDAPName);
break;
case
2:
_principalContext = new PrincipalContext(ContextType.Machine,
LDAPName);
break;
case
3:
_principalContext = new PrincipalContext(ContextType.ApplicationDirectory,
LDAPName);
break;
default:
break;
}
}
#endregion
#region//枚举类型
///
<summary>
///
枚举类型
///
</summary>
public enum
ValidType
{
///
<summary>
///
域
///
</summary>
Domain =
1,
/// <summary>
///
机器
///
</summary>
Machine =
2,
/// <summary>
///
应用程序
///
</summary>
ApplicationDirectory = 3
}
#endregion
#endregion
}
}
7. Impersonator.cs代码部分如下:
using System;
using System.Collections.Generic;
using
System.Linq;
using System.Text;
using
System.Security.Principal;
namespace
TCL.EG.ModifyPasswd
{
public class
Impersonator
{
private
WindowsImpersonationContext ctx =
null;
public bool IsImpersonated {
get; set; }
public void
BeginImpersonation()
{
try
{
if
(!WindowsIdentity.GetCurrent().IsSystem)
{
ctx =
WindowsIdentity.Impersonate(WindowsIdentity.GetCurrent().Token);
IsImpersonated =
true;
}
}
catch
{
IsImpersonated =
false;
}
}
public void
StopImpersonation()
{
if (ctx
!= null)
{
ctx.Undo();
}
}
}
}
8. 部署后,看下效果图:
自定义通知栏效果图:
自定义状态栏效果图:
注意事项:
1、 密码复杂度策略,最好合符要求,否则会提示:密码不合符复杂度策略。要不,干脆不禁用此策略,在代码中用自己定义策略,用正则表达式,如下图:
2、 为了能每天多次修改密码,此时应当禁用如下策略,如下图:
否则定义好,必须按照此策略进行。策略更新后请重启系统或用gpupdate进行策略刷新即可。
原文:http://www.cnblogs.com/914556495wxkj/p/3616046.html