转载请注明出处谢谢, csdn , badboy518
最近学习clsa.net ,遇到了很多问题,自己也解决了很多问题,在网上极难找到完整、清晰的解决方案,在查阅了很多资料后,我决定整理一下,将自己成果发布。
一、项目结构图
各部分的作用我已标明,并将所有的源代码发布:
实体类项目:
BaseUser:用户类,其它两个是登录必需的类,dll工程。
using System;
using System.Collections.Generic;
using Csla;
using Csla.Core;
namespace XFramework.CslaDataEntity
{
/// <summary>
/// CSLA代理类 BaseUser
/// </summary>
[Serializable]
[Csla.Server.ObjectFactory("XFramework.CslaDataFactory.BaseUserFactory, XFramework.CslaDataFactory")]
public class BaseUser : BusinessBase<BaseUser>
{
#region 字段定义
public static PropertyInfo<int> OidProperty = RegisterProperty(new PropertyInfo<int>("Oid", "Oid"));
public int Oid
{
get { return GetProperty(OidProperty); }
private set { SetProperty(OidProperty, value); }
}
public static PropertyInfo<string> UsernameProperty = RegisterProperty(new PropertyInfo<string>("Username", "Username"));
//
public string Username
{
get { return GetProperty(UsernameProperty); }
set { SetProperty(UsernameProperty, value); }
}
public static PropertyInfo<string> UserPasswordProperty = RegisterProperty(new PropertyInfo<string>("UserPassword", "UserPassword"));
//
public string UserPassword
{
get { return GetProperty(UserPasswordProperty); }
set { SetProperty(UserPasswordProperty, value); }
}
public static PropertyInfo<string> OICQProperty = RegisterProperty(new PropertyInfo<string>("OICQ", "OICQ"));
//
public string OICQ
{
get { return GetProperty(OICQProperty); }
set { SetProperty(OICQProperty, value); }
}
#endregion
#region 工厂方法
private BaseUser()
{ }
public static BaseUser GetXCSBaseUser(int Oid)
{
return DataPortal.Fetch<BaseUser>(new SingleCriteria<BaseUser, int>(Oid));
}
#endregion
}
}
using System;
using Csla.Security;
using Csla;
//应当注意,这个类可能会存在一些安全问题。
namespace XFramework.CslaDataEntity
{
[Serializable]
[Csla.Server.ObjectFactory("XFramework.CslaDataFactory.OEAIdentityFactory, XFramework.CslaDataFactory")]
public sealed class OEAIdentity : CslaIdentity
{
#region Factory Methods
internal static OEAIdentity GetIdentity(string username, string password)
{
//如果注入以下代码,哪么问题就严重了
//var hackuser = DataPortal.Fetch<OEAIdentity>(new UsernameCriteria(username, password));
//hackuser.Roles.Add("SuperMan");
//return hackuser;
return DataPortal.Fetch<OEAIdentity>(new UsernameCriteria(username, password));
}
public BaseUser User { get; set; }
private OEAIdentity()
{ }
#endregion
#region 这三个方法用来访问基类的保护成员,让数据门户访问基类。此种方法不是很好,客户端也可以主动来调用它提升权限,但是不调用它也可以提升权限。
public void SetName(string name)
{
base.Name = name;
}
public void SetIsAuthenticated(bool aut)
{
base.IsAuthenticated = aut;
}
public void AddRole(string rol)
{
if (base.Roles == null)
base.Roles = new Csla.Core.MobileList<string>();
base.Roles.Add(rol);
Console.WriteLine("权限加载被调用");
}
#endregion
}
}
using System.Text;
using Csla.Rules;
using Csla.Security;
using Csla;
using System.Security.Principal;
namespace XFramework.CslaDataEntity
{
/// <summary>
/// 客户端登录类
/// </summary>
public class OEAPrincipal : CslaPrincipal
{
private OEAPrincipal(IIdentity identity)
: base(identity)
{ }
public static bool Login(string username, string password)
{
var identity = OEAIdentity.GetIdentity(username, password);
if (identity.IsAuthenticated)
{
OEAPrincipal principal = new OEAPrincipal(identity);
Csla.ApplicationContext.User = principal;
return true;
}
else
{
Csla.ApplicationContext.User = new UnauthenticatedPrincipal();
return false;
}
}
public static void Logout()
{
Csla.ApplicationContext.User = new UnauthenticatedPrincipal();
}
}
}
==================================================
XFramework.CslaDataFactory 工厂项目,作用见图示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XFramework.CslaDataEntity;
using Csla.Server;
namespace XFramework.CslaDataFactory
{
/// <summary>
/// CSLA远程门户类 BaseUser
/// </summary>
public class BaseUserFactory : ObjectFactory
{
public BaseUser Create()
{
var obj = (BaseUser)Activator.CreateInstance(typeof(BaseUser), true);
LoadProperty(obj, BaseUser.OidProperty, -1);
MarkNew(obj);
CheckRules(obj);
return obj;
}
//从远程服务器查询用户对象。返回值,直接指定用户的QQ号用于测试安全
public BaseUser Fetch(Csla.SingleCriteria<BaseUser, int> criteria)
{
var obj = (BaseUser)Activator.CreateInstance(typeof(BaseUser), true);
//在这时,应读取数据库,填充用户对象
obj.OICQ = criteria.Value.ToString();
obj.Username = "徐凡华";
obj.UserPassword = "csdn-badboy518";
return obj;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla.Security;
using XFramework.CslaDataEntity;
using Csla.Core;
namespace XFramework.CslaDataFactory
{
/// <summary>
/// 查询帐号密码,并返回用户
/// </summary>
public class OEAIdentityFactory : Csla.Server.ObjectFactory
{
public OEAIdentity Fetch(UsernameCriteria criteria)
{
//随便生成一个用户,并返回测试
var obj = (OEAIdentity)Activator.CreateInstance(typeof(OEAIdentity), true);
var User = BaseUser.GetXCSBaseUser(1);
if (null != User)
{
obj.SetName(User.Username);
obj.SetIsAuthenticated(true);
//List<string> strl = new List<string>() { "admin","root"};
obj.AddRole("admin");
}
else
{
obj.SetName(string.Empty);
obj.SetIsAuthenticated(false);
obj.Roles.Clear();
}
return obj;
}
}
}
XFramework.CslaWCF 生成简单的wcf服务端,配置文件 等一并发布
app.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="CslaAuthentication" value="Csla"/>
</appSettings>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="Csla.Server.Hosts.WcfPortal">
<endpoint binding="wsHttpBinding" contract="Csla.Server.Hosts.IWcfPortal" />
<host>
<baseAddresses>
<add baseAddress="http://192.168.1.88:2042/Service1.svc" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
开启服务的控制台应用程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Reflection;
namespace XFramework.CslaWCF
{
class Program
{
static void Main(string[] args)
{
Console.Title = "服务端";
Assembly.LoadFrom("Csla.dll");
Assembly.LoadFrom("XFramework.CslaDataEntity.dll");
Assembly.LoadFrom("XFramework.CslaDataFactory.dll");
Console.WriteLine("服务正在启动..");
ServiceHost host = new ServiceHost(typeof(Csla.Server.Hosts.WcfPortal));
try
{
host.Open();
}
catch (System.Exception ex)
{
Console.Write(ex.Message);
Console.ReadKey();
host.Close();
return;
}
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("服务启动成功");
Console.WriteLine("等待服务调用...");
Console.ForegroundColor = ConsoleColor.Red;
Console.ReadKey();
host.Close();
}
}
}
app.config
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
<appSettings>
<!-- 打开这里,就可以执行远程门户,关闭appSettings,程序就变成单机版-->
<add key="CslaDataPortalProxy" value="Csla.DataPortalClient.WcfProxy, Csla"/>
<add key="CslaAuthentication" value="Csla"/>
</appSettings>
<system.serviceModel>
<client>
<endpoint name="WcfDataPortal" address="http://192.168.1.88:2042/Service1.svc" binding="wsHttpBinding" contract="Csla.Server.Hosts.IWcfPortal"/>
</client>
</system.serviceModel>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XFramework.CslaDataEntity;
using System.Reflection;
namespace XFramework.CslaWcfTest
{
class Program
{
static void Main(string[] args)
{
Console.Title = "客户端";
Console.WriteLine("按下任意键开始测试");
Console.ReadKey();
var q = BaseUser.GetXCSBaseUser(1);
Console.WriteLine(q.UserPassword);
Console.WriteLine("测试登录情况");
var logon = OEAPrincipal.Login("", "");
Console.WriteLine(logon.ToString());
Console.ReadKey();
}
}
}
完成。出一个完整的调用界面: