我正在尝试在DotNetNuke 7.4中创建一个支持LinkedId的身份验证提供程序。我使用来自DnnPlatform GIT的Facebook提供商的源包作为基础,并为LinkedIn的oAuth修改了它。我可以通过LinkedIn连接并获取身份验证令牌,但代码失败
OAuthClient.GetCurrentUser<LinkedInUserData>();
由于LinkedInUserData为null。具体的记录错误是
DotNetNuke.Services.Exceptions.Exceptions - ~/Default.aspx?tabid=55&error=An unexpected error has occurred
System.ArgumentNullException: Value cannot be null.
Parameter name: value
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at DotNetNuke.Services.Authentication.OAuth.OAuthClientBase.GetCurrentUser[TUserData]()
at DotNetNuke.Authentication.LinkedIn.Login.GetCurrentUser() in c:\Websites\dnndev74_2\DesktopModules\AuthenticationServices\LinkedIn\Login.ascx.cs:line 103
下面是3个正在运行的类,有很多继承正在进行,所以我很难理解LinkedInUserData如何首先填充的机制。在笔记上。当我从GIT获取facebook代码库并将其作为提供商安装在我的本地时,并尝试注册Facebook帐户,我得到相同的错误。但是,如果我通过CMS安装提供程序它运行正常或使用dnn 7.4安装附带的DLL,Facebook工作。因此,我认为GIT代码存在根本性缺陷。
LinkedInClient.cs
namespace DotNetNuke.Authentication.LinkedIn.Components
{
public class LinkedInClient : OAuthClientBase
{
#region Constructors
public LinkedInClient(int portalId, AuthMode mode)
: base(portalId, mode, "LinkedIn")
{
base.AuthorizationEndpoint = new Uri("https://www.linkedin.com/uas/oauth2/authorization");
base.RequestTokenEndpoint = new Uri("https://api.linkedin.com/uas/oauth/requestToken?scope=r_emailaddress");
base.TokenMethod = HttpMethod.POST;
base.TokenEndpoint = new Uri("https://www.linkedin.com/uas/oauth2/accessToken");
base.MeGraphEndpoint = new Uri("https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,formatted-name,picture-url)?format=json");
base.AuthTokenName = "LinkedInUserToken";
base.OAuthVersion = "2.0";
base.LoadTokenCookie(string.Empty);
}
#endregion
protected override TimeSpan GetExpiry(string responseText)
{
var jsonSerializer = new JavaScriptSerializer();
var tokenDictionary = jsonSerializer.DeserializeObject(responseText) as Dictionary<string, object>;
return new TimeSpan(0, 0, Convert.ToInt32(tokenDictionary["expires_in"]));
}
protected override string GetToken(string responseText)
{
var jsonSerializer = new JavaScriptSerializer();
var tokenDictionary = jsonSerializer.DeserializeObject(responseText) as Dictionary<string, object>;
return Convert.ToString(tokenDictionary["access_token"]);
}
}
}
LinkedInUserData.cs
namespace DotNetNuke.Authentication.LinkedIn.Components
{
[DataContract]
[Serializable]
public class LinkedInUserData : UserData
{
#region Overrides
public override string FirstName
{
get { return LinkedInFirstName; }
set { }
}
public override string LastName
{
get { return LinkedInLastName; }
set { }
}
public override string Email
{
get { return emailAddress; }
set { }
}
public override string ProfileImage
{
get { return LinkedInPictureUrl; }
set { }
}
#endregion
[DataMember(Name = "first-name")]
public string LinkedInFirstName { get; set; }
[DataMember(Name = "last-name")]
public string LinkedInLastName { get; set; }
[DataMember(Name = "picture-url")]
public string LinkedInPictureUrl { get; set; }
[DataMember(Name = "email-address")]
public string emailAddress { set; get; }
}
Login.cs
namespace DotNetNuke.Authentication.LinkedIn
{
public partial class Login : OAuthLoginBase
{
protected override string AuthSystemApplicationName
{
get { return "LinkedIn"; }
}
public override bool SupportsRegistration
{
get { return true; }
}
protected override UserData GetCurrentUser()
{
return OAuthClient.GetCurrentUser<LinkedInUserData>();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
loginButton.Click += loginButton_Click;
registerButton.Click += loginButton_Click;
OAuthClient = new LinkedInClient(PortalId, Mode);
loginItem.Visible = (Mode == AuthMode.Login);
registerItem.Visible = (Mode == AuthMode.Register);
}
protected override void AddCustomProperties(NameValueCollection properties)
{
base.AddCustomProperties(properties);
properties.Add("LinkedIn", OAuthClient.GetCurrentUser<LinkedInUserData>().Link.ToString());
}
private void loginButton_Click(object sender, EventArgs e)
{
AuthorisationResult result = OAuthClient.Authorize();
if (result == AuthorisationResult.Denied)
{
UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("PrivateConfirmationMessage", Localization.SharedResourceFile), ModuleMessage.ModuleMessageType.YellowWarning);
}
}
}
}
答案 0 :(得分:0)
标记,
几年前我为Linkedin写了一个DNN提供商。将我的代码与您的代码进行比较,我的第一件事是重定向用户以获取访问令牌。用于获取访问令牌和用户许可的基本URL是:www.linkedin.com/uas/oauth2。我必须传递我的链接API密钥,重定向Url以及来自提供程序设置的一些其他数据。
我的重定向网址与加载我的提供商的默认门户网站登录页面相同。一旦用户允许LinkedIn允许我的应用程序访问并验证他已登录,重定向回我的提供者将在Request.Cookies中查找LinkedInAuthToken cookie。验证令牌有效后,我可以对/ v1 / people / API进行额外的API调用,以获取用户数据,以完成对DNN的任何类型的自动注册或自动配置文件更新。
在获取oauth访问cookie之前,您的提供商似乎会立即尝试用户数据查找API调用。
我的LinkedIn提供商的代码不是开源的,但我想我可以从我的工作中获得许可以公开它。如果您对此感兴趣,请给我留言。