├── Microsoft.Owin.Security.WeChat
├── nuget.exe
├── Microsoft.Owin.Security.WeChat.1.0.0.0.nupkg
├── Microsoft.Owin.Security.WeChat.1.0.0.1.nupkg
├── Provider
│ ├── IWeChatAuthenticationProvider.cs
│ ├── WeChatReturnEndpointContext.cs
│ ├── WeChatAuthenticationProvider.cs
│ └── WeChatAuthenticatedContext.cs
├── Microsoft.Owin.Security.WeChat.nuspec
├── WeChatAuthenticationExtensions.cs
├── WeChatAuthenticationOptions.cs
├── Properties
│ └── AssemblyInfo.cs
├── WeChatAuthenticationMiddleware.cs
├── Microsoft.Owin.Security.WeChat.csproj
└── WeChatAccountAuthenticationHandler.cs
├── Microsoft.Owin.Security.QQ
├── packages.config
├── Provider
│ ├── IQQConnectAuthenticationProvider.cs
│ ├── QQConnectReturnEndpointContext.cs
│ ├── QQConnectAuthenticationProvider.cs
│ └── QQConnectAuthenticatedContext.cs
├── Properties
│ └── AssemblyInfo.cs
├── QQConnectAuthenticationExtensions.cs
├── QQConnectAuthenticationOptions.cs
├── QQConnectAuthenticationMiddleware.cs
├── Microsoft.Owin.Security.QQ.csproj
└── QQConnectAccountAuthenticationHandler.cs
├── README.md
├── Microsoft.Owin.Security.Solution.sln
├── .gitattributes
└── .gitignore
/Microsoft.Owin.Security.WeChat/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momyh/Microsoft.Owin.Security.Solution/HEAD/Microsoft.Owin.Security.WeChat/nuget.exe
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.1.0.0.0.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momyh/Microsoft.Owin.Security.Solution/HEAD/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.1.0.0.0.nupkg
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.1.0.0.1.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momyh/Microsoft.Owin.Security.Solution/HEAD/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.1.0.0.1.nupkg
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Provider/IWeChatAuthenticationProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Microsoft.Owin.Security.WeChat
8 | {
9 | public interface IWeChatAuthenticationProvider
10 | {
11 | Task Authenticated(WeChatAuthenticatedContext context);
12 | Task ReturnEndpoint(WeChatReturnEndpointContext context);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microsoft.Owin.Security.Solution is the asp.net mvc5 solution extentions for china developer
2 |
3 | this solution is the Microsoft.Owin.Security extention,is extention the china qq and weixin login with asp.net identity
4 |
5 | How to use:
6 | Add below code to asp.net mvc5 project App_Start/Startup.Auth.cs
7 |
8 | app.UseQQConnectAuthentication(appId: "***",appSecret: "*****");
9 |
10 | app.UseWeChatAuthentication(appId: "***",appSecret: "*****");
11 |
12 | 这个工程系对asp.net identity的一个扩展,在asp.net mvc5的基础上增加了中国国内的QQ和微信登陆,用于解决新网站集成这两种登陆方式的麻烦,欢迎其他人员贡献代码。
13 |
14 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Provider/WeChatReturnEndpointContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Microsoft.Owin;
6 | using Microsoft.Owin.Security;
7 | using Microsoft.Owin.Security.Provider;
8 |
9 | namespace Microsoft.Owin.Security.WeChat
10 | {
11 | public class WeChatReturnEndpointContext : ReturnEndpointContext
12 | {
13 | public WeChatReturnEndpointContext(
14 | IOwinContext context,
15 | AuthenticationTicket ticket)
16 | : base(context, ticket)
17 | {
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Provider/WeChatAuthenticationProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Microsoft.Owin.Security.WeChat
8 | {
9 | public class WeChatAuthenticationProvider : IWeChatAuthenticationProvider
10 | {
11 | public WeChatAuthenticationProvider()
12 | {
13 | onAuthenticated = (c) => Task.FromResult(null);
14 | onReturnEndpoint = (c) => Task.FromResult(null);
15 | }
16 |
17 | public Func onAuthenticated { get; set; }
18 | public Func onReturnEndpoint { get; set; }
19 |
20 | public Task Authenticated(WeChatAuthenticatedContext context)
21 | {
22 | return onAuthenticated(context);
23 | }
24 |
25 | public Task ReturnEndpoint(WeChatReturnEndpointContext context)
26 | {
27 | return onReturnEndpoint(context);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Provider/IQQConnectAuthenticationProvider.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Linq;
19 | using System.Text;
20 | using System.Threading.Tasks;
21 |
22 | namespace Microsoft.Owin.Security.WeChat
23 | {
24 | public interface IQQConnectAuthenticationProvider
25 | {
26 | Task Authenticated(QQConnectAuthenticatedContext context);
27 | Task ReturnEndpoint(QQConnectReturnEndpointContext context);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Owin.Security.WeChat
5 | 1.0.0.1
6 | Momy
7 | Momy
8 | http://www.yn-s.com
9 | https://github.com/momyh/Microsoft.Owin.Security.Solution
10 | http://www.yn-s.com
11 | false
12 | Middleware that enables an application to support WeChat/QQ OAuth 2.0 authentication workflow.
13 | ASP.NET MVC 5 OAuth.0 Login
14 | Copyright 2015
15 | Owin Weixin Wechat Microsoft.Owin.Security.WeChat Microsoft.Owin.Security.Weixin
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/WeChatAuthenticationExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Owin.Security.WeChat;
3 | using Microsoft.Owin.Security;
4 |
5 | namespace Owin
6 | {
7 | public static class WeChatAuthenticationExtensions
8 | {
9 | public static void UseWeChatAuthentication(this IAppBuilder app, WeChatAuthenticationOptions options)
10 | {
11 | if (app == null)
12 | {
13 | throw new ArgumentNullException("app");
14 | }
15 | if (options == null)
16 | {
17 | throw new ArgumentNullException("options");
18 | }
19 |
20 | app.Use(typeof(WeChatAuthenticationMiddleware), app, options);
21 | }
22 |
23 | public static void UseWeChatAuthentication(this IAppBuilder app, string appId, string appSecret)
24 | {
25 | UseWeChatAuthentication(app, new WeChatAuthenticationOptions()
26 | {
27 | AppId = appId,
28 | AppSecret = appSecret,
29 | SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType()
30 | });
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Provider/QQConnectReturnEndpointContext.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Linq;
19 | using System.Text;
20 | using Microsoft.Owin;
21 | using Microsoft.Owin.Security;
22 | using Microsoft.Owin.Security.Provider;
23 |
24 | namespace Microsoft.Owin.Security.WeChat
25 | {
26 | public class QQConnectReturnEndpointContext : ReturnEndpointContext
27 | {
28 | public QQConnectReturnEndpointContext(
29 | IOwinContext context,
30 | AuthenticationTicket ticket)
31 | : base(context, ticket)
32 | {
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Provider/WeChatAuthenticatedContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Security.Claims;
5 | using System.Text;
6 | using Microsoft.Owin;
7 | using Microsoft.Owin.Security;
8 | using Microsoft.Owin.Security.Provider;
9 | using Newtonsoft.Json.Linq;
10 |
11 | namespace Microsoft.Owin.Security.WeChat
12 | {
13 | public class WeChatAuthenticatedContext : BaseContext
14 | {
15 | public WeChatAuthenticatedContext(IOwinContext context,string openId, JObject user, string accessToken)
16 | :base(context)
17 | {
18 | IDictionary userAsDictionary = user;
19 |
20 | User = user;
21 | AccessToken = accessToken;
22 |
23 | Id = openId;
24 | Name = PropertyValueIfExists("nickname", userAsDictionary);
25 | }
26 |
27 | public JObject User { get; private set; }
28 | public string AccessToken { get; private set; }
29 |
30 | public string Id { get; private set; }
31 | public string Name { get; private set; }
32 |
33 | public ClaimsIdentity Identity { get; set; }
34 | public AuthenticationProperties Properties { get; set; }
35 |
36 | private static string PropertyValueIfExists(string property, IDictionary dictionary)
37 | {
38 | return dictionary.ContainsKey(property) ? dictionary[property].ToString() : null;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.Solution.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.WeChat", "Microsoft.Owin.Security.WeChat\Microsoft.Owin.Security.WeChat.csproj", "{A9A0BA07-5273-4D93-A398-E5F94177CC38}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.QQ", "Microsoft.Owin.Security.QQ\Microsoft.Owin.Security.QQ.csproj", "{2B96497A-C363-473A-BDD4-CC390B7ADB96}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {A9A0BA07-5273-4D93-A398-E5F94177CC38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {A9A0BA07-5273-4D93-A398-E5F94177CC38}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {A9A0BA07-5273-4D93-A398-E5F94177CC38}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {A9A0BA07-5273-4D93-A398-E5F94177CC38}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {2B96497A-C363-473A-BDD4-CC390B7ADB96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {2B96497A-C363-473A-BDD4-CC390B7ADB96}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {2B96497A-C363-473A-BDD4-CC390B7ADB96}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {2B96497A-C363-473A-BDD4-CC390B7ADB96}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/WeChatAuthenticationOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net.Http;
4 | using Microsoft.Owin.Security;
5 |
6 | namespace Microsoft.Owin.Security.WeChat
7 | {
8 | public class WeChatAuthenticationOptions : AuthenticationOptions
9 | {
10 | public const string AUTHENTICATION_TYPE = "WeChat";
11 | public WeChatAuthenticationOptions()
12 | : base(AUTHENTICATION_TYPE)
13 | {
14 | Caption = "微信账号";
15 | ReturnEndpointPath = "/signin-wechatconnect";
16 | AuthenticationMode = AuthenticationMode.Passive;
17 | Scope = new List { "get_user_info" };
18 | BackchannelTimeout = TimeSpan.FromSeconds(60);
19 | }
20 |
21 | public ISecureDataFormat StateDataFormat { get; set; }
22 |
23 | public TimeSpan BackchannelTimeout { get; set; }
24 |
25 | public WebRequestHandler BackchannelHttpHandler { get; set; }
26 |
27 | public IWeChatAuthenticationProvider Provider { get; set; }
28 |
29 | public ICertificateValidator BackchannelCertificateValidator { get; set; }
30 |
31 | public IList Scope { get; private set; }
32 |
33 | public string ReturnEndpointPath { get; set; }
34 |
35 | public string SignInAsAuthenticationType { get; set; }
36 |
37 | public string Caption
38 | {
39 | get { return Description.Caption; }
40 | set { Description.Caption = value; }
41 | }
42 |
43 | public string AppId { get; set; }
44 |
45 | public string AppSecret { get; set; }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Microsoft.Owin.Security.QQ")]
9 | [assembly: AssemblyDescription("Middleware that enables an application to support QQConnect OAuth 2.0 authentication workflow.")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("momy")]
12 | [assembly: AssemblyProduct("Microsoft.Owin.Security.QQ")]
13 | [assembly: AssemblyCopyright("Copyright © momy 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("3b4e1164-4e9b-423e-b900-efa4996dd2c9")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Microsoft.Owin.Security.WeChat")]
9 | [assembly: AssemblyDescription("Middleware that enables an application to support WeChat OAuth 2.0 authentication workflow.")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("momy")]
12 | [assembly: AssemblyProduct("Microsoft.Owin.Security.WeChat")]
13 | [assembly: AssemblyCopyright("Copyright © momy 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("68107e44-ab82-4b66-b651-add2cad0c0ed")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.1")]
36 | [assembly: AssemblyFileVersion("1.0.0.1")]
37 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Provider/QQConnectAuthenticationProvider.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Linq;
19 | using System.Text;
20 | using System.Threading.Tasks;
21 |
22 | namespace Microsoft.Owin.Security.WeChat
23 | {
24 | public class QQConnectAuthenticationProvider : IQQConnectAuthenticationProvider
25 | {
26 | public QQConnectAuthenticationProvider()
27 | {
28 | onAuthenticated = (c) => Task.FromResult(null);
29 | onReturnEndpoint = (c) => Task.FromResult(null);
30 | }
31 |
32 | public Func onAuthenticated { get; set; }
33 | public Func onReturnEndpoint { get; set; }
34 |
35 | public Task Authenticated(QQConnectAuthenticatedContext context)
36 | {
37 | return onAuthenticated(context);
38 | }
39 |
40 | public Task ReturnEndpoint(QQConnectReturnEndpointContext context)
41 | {
42 | return onReturnEndpoint(context);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/QQConnectAuthenticationExtensions.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using Microsoft.Owin.Security.WeChat;
18 | using Microsoft.Owin.Security;
19 |
20 | namespace Owin
21 | {
22 | public static class QQConnectAuthenticationExtensions
23 | {
24 | public static void UseQQConnectAuthentication(this IAppBuilder app, QQConnectAuthenticationOptions options)
25 | {
26 | if (app == null)
27 | {
28 | throw new ArgumentNullException("app");
29 | }
30 | if (options == null)
31 | {
32 | throw new ArgumentNullException("options");
33 | }
34 |
35 | app.Use(typeof(QQConnectAuthenticationMiddleware), app, options);
36 | }
37 |
38 | public static void UseQQConnectAuthentication(this IAppBuilder app, string appId, string appSecret)
39 | {
40 | UseQQConnectAuthentication(app, new QQConnectAuthenticationOptions()
41 | {
42 | AppId = appId,
43 | AppSecret = appSecret,
44 | SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType()
45 | });
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Provider/QQConnectAuthenticatedContext.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Linq;
19 | using System.Security.Claims;
20 | using System.Text;
21 | using Microsoft.Owin;
22 | using Microsoft.Owin.Security;
23 | using Microsoft.Owin.Security.Provider;
24 | using Newtonsoft.Json.Linq;
25 |
26 | namespace Microsoft.Owin.Security.WeChat
27 | {
28 | public class QQConnectAuthenticatedContext : BaseContext
29 | {
30 | public QQConnectAuthenticatedContext(IOwinContext context,string openId, JObject user, string accessToken)
31 | :base(context)
32 | {
33 | IDictionary userAsDictionary = user;
34 |
35 | User = user;
36 | AccessToken = accessToken;
37 |
38 | Id = openId;
39 | Name = PropertyValueIfExists("nickname", userAsDictionary);
40 | }
41 |
42 | public JObject User { get; private set; }
43 | public string AccessToken { get; private set; }
44 |
45 | public string Id { get; private set; }
46 | public string Name { get; private set; }
47 |
48 | public ClaimsIdentity Identity { get; set; }
49 | public AuthenticationProperties Properties { get; set; }
50 |
51 | private static string PropertyValueIfExists(string property, IDictionary dictionary)
52 | {
53 | return dictionary.ContainsKey(property) ? dictionary[property].ToString() : null;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/QQConnectAuthenticationOptions.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Net.Http;
19 | using Microsoft.Owin.Security;
20 |
21 | namespace Microsoft.Owin.Security.WeChat
22 | {
23 | public class QQConnectAuthenticationOptions : AuthenticationOptions
24 | {
25 | public const string AUTHENTICATION_TYPE = "QQConnect";
26 | public QQConnectAuthenticationOptions()
27 | : base(AUTHENTICATION_TYPE)
28 | {
29 | Caption = "QQ账号";
30 | ReturnEndpointPath = "/signin-qqconnect";
31 | AuthenticationMode = AuthenticationMode.Passive;
32 | Scope = new List { "get_user_info" };
33 | BackchannelTimeout = TimeSpan.FromSeconds(60);
34 | }
35 |
36 | public ISecureDataFormat StateDataFormat { get; set; }
37 |
38 | public TimeSpan BackchannelTimeout { get; set; }
39 |
40 | public WebRequestHandler BackchannelHttpHandler { get; set; }
41 |
42 | public IQQConnectAuthenticationProvider Provider { get; set; }
43 |
44 | public ICertificateValidator BackchannelCertificateValidator { get; set; }
45 |
46 | public IList Scope { get; private set; }
47 |
48 | public string ReturnEndpointPath { get; set; }
49 |
50 | public string SignInAsAuthenticationType { get; set; }
51 |
52 | public string Caption
53 | {
54 | get { return Description.Caption; }
55 | set { Description.Caption = value; }
56 | }
57 |
58 | public string AppId { get; set; }
59 |
60 | public string AppSecret { get; set; }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/WeChatAuthenticationMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using Microsoft.Owin;
4 | using Microsoft.Owin.Logging;
5 | using Microsoft.Owin.Security.DataHandler;
6 | using Microsoft.Owin.Security.DataProtection;
7 | using Microsoft.Owin.Security.Infrastructure;
8 | using Owin;
9 |
10 | namespace Microsoft.Owin.Security.WeChat
11 | {
12 | public class WeChatAuthenticationMiddleware :AuthenticationMiddleware
13 | {
14 | private readonly ILogger _logger;
15 | private readonly HttpClient _httpClient;
16 |
17 | public WeChatAuthenticationMiddleware(
18 | OwinMiddleware next,
19 | IAppBuilder app,
20 | WeChatAuthenticationOptions options)
21 | : base(next, options)
22 | {
23 | _logger = app.CreateLogger();
24 |
25 | if (Options.Provider == null)
26 | {
27 | Options.Provider = new WeChatAuthenticationProvider();
28 | }
29 | if (Options.StateDataFormat == null)
30 | {
31 | var dataProtecter = app.CreateDataProtector(
32 | typeof(WeChatAuthenticationMiddleware).FullName,
33 | Options.AuthenticationType, "v1");
34 | Options.StateDataFormat = new PropertiesDataFormat(dataProtecter);
35 | }
36 |
37 | _httpClient = new HttpClient(ResolveHttpMessageHandler(Options));
38 | _httpClient.Timeout = Options.BackchannelTimeout;
39 | _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
40 | }
41 |
42 | protected override AuthenticationHandler CreateHandler()
43 | {
44 | return new WeChatAccountAuthenticationHandler(_httpClient, _logger);
45 | }
46 |
47 | private static HttpMessageHandler ResolveHttpMessageHandler(WeChatAuthenticationOptions options)
48 | {
49 | HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler();
50 |
51 | // If they provided a validator, apply it or fail.
52 | if (options.BackchannelCertificateValidator != null)
53 | {
54 | // Set the cert validate callback
55 | WebRequestHandler webRequestHandler = handler as WebRequestHandler;
56 | if (webRequestHandler == null)
57 | {
58 | throw new InvalidOperationException("An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.");
59 | }
60 | webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
61 | }
62 |
63 | return handler;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/QQConnectAuthenticationMiddleware.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Feifan Tang. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | using System;
17 | using System.Net.Http;
18 | using Microsoft.Owin;
19 | using Microsoft.Owin.Logging;
20 | using Microsoft.Owin.Security.DataHandler;
21 | using Microsoft.Owin.Security.DataProtection;
22 | using Microsoft.Owin.Security.Infrastructure;
23 | using Owin;
24 |
25 | namespace Microsoft.Owin.Security.WeChat
26 | {
27 | public class QQConnectAuthenticationMiddleware :AuthenticationMiddleware
28 | {
29 | private readonly ILogger _logger;
30 | private readonly HttpClient _httpClient;
31 |
32 | public QQConnectAuthenticationMiddleware(
33 | OwinMiddleware next,
34 | IAppBuilder app,
35 | QQConnectAuthenticationOptions options)
36 | : base(next, options)
37 | {
38 | _logger = app.CreateLogger();
39 |
40 | if (Options.Provider == null)
41 | {
42 | Options.Provider = new QQConnectAuthenticationProvider();
43 | }
44 | if (Options.StateDataFormat == null)
45 | {
46 | var dataProtecter = app.CreateDataProtector(
47 | typeof(QQConnectAuthenticationMiddleware).FullName,
48 | Options.AuthenticationType, "v1");
49 | Options.StateDataFormat = new PropertiesDataFormat(dataProtecter);
50 | }
51 |
52 | _httpClient = new HttpClient(ResolveHttpMessageHandler(Options));
53 | _httpClient.Timeout = Options.BackchannelTimeout;
54 | _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
55 | }
56 |
57 | protected override AuthenticationHandler CreateHandler()
58 | {
59 | return new QQConnectAccountAuthenticationHandler(_httpClient, _logger);
60 | }
61 |
62 | private static HttpMessageHandler ResolveHttpMessageHandler(QQConnectAuthenticationOptions options)
63 | {
64 | HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler();
65 |
66 | // If they provided a validator, apply it or fail.
67 | if (options.BackchannelCertificateValidator != null)
68 | {
69 | // Set the cert validate callback
70 | WebRequestHandler webRequestHandler = handler as WebRequestHandler;
71 | if (webRequestHandler == null)
72 | {
73 | throw new InvalidOperationException("An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.");
74 | }
75 | webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
76 | }
77 |
78 | return handler;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # Roslyn cache directories
20 | *.ide/
21 |
22 | # MSTest test Results
23 | [Tt]est[Rr]esult*/
24 | [Bb]uild[Ll]og.*
25 |
26 | #NUNIT
27 | *.VisualState.xml
28 | TestResult.xml
29 |
30 | # Build Results of an ATL Project
31 | [Dd]ebugPS/
32 | [Rr]eleasePS/
33 | dlldata.c
34 |
35 | *_i.c
36 | *_p.c
37 | *_i.h
38 | *.ilk
39 | *.meta
40 | *.obj
41 | *.pch
42 | *.pdb
43 | *.pgc
44 | *.pgd
45 | *.rsp
46 | *.sbr
47 | *.tlb
48 | *.tli
49 | *.tlh
50 | *.tmp
51 | *.tmp_proj
52 | *.log
53 | *.vspscc
54 | *.vssscc
55 | .builds
56 | *.pidb
57 | *.svclog
58 | *.scc
59 |
60 | # Chutzpah Test files
61 | _Chutzpah*
62 |
63 | # Visual C++ cache files
64 | ipch/
65 | *.aps
66 | *.ncb
67 | *.opensdf
68 | *.sdf
69 | *.cachefile
70 |
71 | # Visual Studio profiler
72 | *.psess
73 | *.vsp
74 | *.vspx
75 |
76 | # TFS 2012 Local Workspace
77 | $tf/
78 |
79 | # Guidance Automation Toolkit
80 | *.gpState
81 |
82 | # ReSharper is a .NET coding add-in
83 | _ReSharper*/
84 | *.[Rr]e[Ss]harper
85 | *.DotSettings.user
86 |
87 | # JustCode is a .NET coding addin-in
88 | .JustCode
89 |
90 | # TeamCity is a build add-in
91 | _TeamCity*
92 |
93 | # DotCover is a Code Coverage Tool
94 | *.dotCover
95 |
96 | # NCrunch
97 | _NCrunch_*
98 | .*crunch*.local.xml
99 |
100 | # MightyMoose
101 | *.mm.*
102 | AutoTest.Net/
103 |
104 | # Web workbench (sass)
105 | .sass-cache/
106 |
107 | # Installshield output folder
108 | [Ee]xpress/
109 |
110 | # DocProject is a documentation generator add-in
111 | DocProject/buildhelp/
112 | DocProject/Help/*.HxT
113 | DocProject/Help/*.HxC
114 | DocProject/Help/*.hhc
115 | DocProject/Help/*.hhk
116 | DocProject/Help/*.hhp
117 | DocProject/Help/Html2
118 | DocProject/Help/html
119 |
120 | # Click-Once directory
121 | publish/
122 |
123 | # Publish Web Output
124 | *.[Pp]ublish.xml
125 | *.azurePubxml
126 | ## TODO: Comment the next line if you want to checkin your
127 | ## web deploy settings but do note that will include unencrypted
128 | ## passwords
129 | #*.pubxml
130 |
131 | # NuGet Packages Directory
132 | packages/*
133 | ## TODO: If the tool you use requires repositories.config
134 | ## uncomment the next line
135 | #!packages/repositories.config
136 |
137 | # Enable "build/" folder in the NuGet Packages folder since
138 | # NuGet packages use it for MSBuild targets.
139 | # This line needs to be after the ignore of the build folder
140 | # (and the packages folder if the line above has been uncommented)
141 | !packages/build/
142 | *.nuspec
143 | *.nupkg
144 | nuget.exe
145 |
146 | # Windows Azure Build Output
147 | csx/
148 | *.build.csdef
149 |
150 | # Windows Store app package directory
151 | AppPackages/
152 |
153 | # Others
154 | sql/
155 | *.Cache
156 | ClientBin/
157 | [Ss]tyle[Cc]op.*
158 | ~$*
159 | *~
160 | *.dbmdl
161 | *.dbproj.schemaview
162 | *.pfx
163 | *.publishsettings
164 | node_modules/
165 |
166 | # RIA/Silverlight projects
167 | Generated_Code/
168 |
169 | # Backup & report files from converting an old project file
170 | # to a newer Visual Studio version. Backup files are not needed,
171 | # because we have git ;-)
172 | _UpgradeReport_Files/
173 | Backup*/
174 | UpgradeLog*.XML
175 | UpgradeLog*.htm
176 |
177 | # SQL Server files
178 | *.mdf
179 | *.ldf
180 |
181 | # Business Intelligence projects
182 | *.rdl.data
183 | *.bim.layout
184 | *.bim_*.settings
185 |
186 | # Microsoft Fakes
187 | FakesAssemblies/
188 |
189 | # LightSwitch generated files
190 | GeneratedArtifacts/
191 | _Pvt_Extensions/
192 | ModelManifest.xml
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/Microsoft.Owin.Security.WeChat.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A9A0BA07-5273-4D93-A398-E5F94177CC38}
8 | Library
9 | Properties
10 | Microsoft.Owin.Security.WeChat
11 | Microsoft.Owin.Security.WeChat
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 | ..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll
38 |
39 |
40 | ..\packages\Microsoft.Owin.Security.2.0.2\lib\net45\Microsoft.Owin.Security.dll
41 |
42 |
43 | False
44 | ..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll
45 |
46 |
47 | ..\packages\Owin.1.0\lib\net40\Owin.dll
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
74 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.QQ/Microsoft.Owin.Security.QQ.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {2B96497A-C363-473A-BDD4-CC390B7ADB96}
8 | Library
9 | Properties
10 | Microsoft.Owin.Security.WeChat
11 | Microsoft.Owin.Security.QQ
12 | v4.5
13 | 512
14 | ..\
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 |
28 |
29 | none
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 |
39 | False
40 | ..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll
41 |
42 |
43 | False
44 | ..\packages\Microsoft.Owin.Security.2.0.2\lib\net45\Microsoft.Owin.Security.dll
45 |
46 |
47 | False
48 | ..\..\LinliboyWebsite\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll
49 |
50 |
51 | False
52 | ..\packages\Owin.1.0\lib\net40\Owin.dll
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
83 |
--------------------------------------------------------------------------------
/Microsoft.Owin.Security.WeChat/WeChatAccountAuthenticationHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net.Http;
4 | using System.Security.Claims;
5 | using System.Threading.Tasks;
6 | using Microsoft.Owin;
7 | using Microsoft.Owin.Logging;
8 | using Microsoft.Owin.Security;
9 | using Microsoft.Owin.Security.Infrastructure;
10 | using Newtonsoft.Json;
11 | using Newtonsoft.Json.Linq;
12 |
13 | namespace Microsoft.Owin.Security.WeChat
14 | {
15 | internal class WeChatAccountAuthenticationHandler : AuthenticationHandler
16 | {
17 | private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
18 | private const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
19 | private const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
20 | private const string UserInfoEndpoint = "https://api.weixin.qq.com/sns/userinfo";
21 | private const string OpenIDEndpoint = "https://api.weixin.qq.com/sns/oauth2";
22 |
23 | private readonly HttpClient _httpClient;
24 | private readonly ILogger _logger;
25 |
26 | public WeChatAccountAuthenticationHandler(HttpClient httpClient, ILogger logger)
27 | {
28 | this._httpClient = httpClient;
29 | this._logger = logger;
30 | }
31 |
32 | public override async Task InvokeAsync()
33 | {
34 | if (Options.ReturnEndpointPath != null &&
35 | String.Equals(Options.ReturnEndpointPath, Request.Path.Value, StringComparison.OrdinalIgnoreCase))
36 | {
37 | return await InvokeReturnPathAsync();
38 | }
39 | return false;
40 | }
41 |
42 | private async Task InvokeReturnPathAsync()
43 | {
44 | _logger.WriteVerbose("InvokeReturnPath");
45 |
46 | var model = await AuthenticateAsync();
47 |
48 | var context = new WeChatReturnEndpointContext(Context, model);
49 | context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType;
50 | context.RedirectUri = model.Properties.RedirectUri;
51 | model.Properties.RedirectUri = null;
52 |
53 | await Options.Provider.ReturnEndpoint(context);
54 |
55 | if (context.SignInAsAuthenticationType != null && context.Identity != null)
56 | {
57 | ClaimsIdentity signInIdentity = context.Identity;
58 | if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal))
59 | {
60 | signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType);
61 | }
62 | Context.Authentication.SignIn(context.Properties, signInIdentity);
63 | }
64 |
65 | if (!context.IsRequestCompleted && context.RedirectUri != null)
66 | {
67 | Response.Redirect(context.RedirectUri);
68 | context.RequestCompleted();
69 | }
70 |
71 | return context.IsRequestCompleted;
72 | }
73 |
74 | protected override async Task AuthenticateCoreAsync()
75 | {
76 | _logger.WriteVerbose("AuthenticateCore");
77 |
78 | AuthenticationProperties properties = null;
79 |
80 | try
81 | {
82 | string code = null;
83 | string state = null;
84 |
85 | IReadableStringCollection query = Request.Query;
86 | IList values = query.GetValues("code");
87 | if (values != null && values.Count == 1)
88 | {
89 | code = values[0];
90 | }
91 | values = query.GetValues("state");
92 | if (values != null && values.Count == 1)
93 | {
94 | state = values[0];
95 | }
96 |
97 | properties = Options.StateDataFormat.Unprotect(state);
98 | if (properties == null)
99 | {
100 | return null;
101 | }
102 |
103 | // OAuth2 10.12 CSRF
104 | if (!ValidateCorrelationId(properties, _logger))
105 | {
106 | return new AuthenticationTicket(null, properties);
107 | }
108 |
109 | var tokenRequestParameters = new List>()
110 | {
111 | new KeyValuePair("appid", Options.AppId),
112 | new KeyValuePair("secret", Options.AppSecret),
113 | new KeyValuePair("code", code),
114 | new KeyValuePair("grant_type", "authorization_code"),
115 | };
116 |
117 | FormUrlEncodedContent requestContent = new FormUrlEncodedContent(tokenRequestParameters);
118 |
119 | HttpResponseMessage response = await _httpClient.PostAsync(TokenEndpoint, requestContent, Request.CallCancelled);
120 | response.EnsureSuccessStatusCode();
121 | string oauthTokenResponse = await response.Content.ReadAsStringAsync();
122 | JsonSerializer js = new JsonSerializer();
123 | AccessTokenResult tokenResult= js.Deserialize(new JsonTextReader(new System.IO.StringReader(oauthTokenResponse)));
124 | if (tokenResult == null || tokenResult.access_token == null)
125 | {
126 | _logger.WriteWarning("Access token was not found");
127 | return new AuthenticationTicket(null, properties);
128 | }
129 |
130 | string userInfoUri = UserInfoEndpoint +
131 | "?access_token=" + Uri.EscapeDataString(tokenResult.access_token) +
132 | "&openid=" + Uri.EscapeDataString(tokenResult.openid);
133 | HttpResponseMessage userInfoResponse = await _httpClient.GetAsync(userInfoUri, Request.CallCancelled);
134 | userInfoResponse.EnsureSuccessStatusCode();
135 | string userInfoString = await userInfoResponse.Content.ReadAsStringAsync();
136 | JObject userInfo = JObject.Parse(userInfoString);
137 |
138 | var context = new WeChatAuthenticatedContext(Context, tokenResult.openid, userInfo, tokenResult.access_token);
139 | context.Identity = new ClaimsIdentity(new[]{
140 | new Claim(ClaimTypes.NameIdentifier, context.Id,XmlSchemaString,Options.AuthenticationType),
141 | new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name,XmlSchemaString,Options.AuthenticationType),
142 | new Claim("urn:wechatconnect:id", context.Id,XmlSchemaString,Options.AuthenticationType),
143 | new Claim("urn:wechatconnect:name", context.Name,XmlSchemaString,Options.AuthenticationType),
144 | });
145 |
146 | await Options.Provider.Authenticated(context);
147 |
148 | context.Properties = properties;
149 |
150 | return new AuthenticationTicket(context.Identity, context.Properties);
151 | }
152 | catch (Exception ex)
153 | {
154 | _logger.WriteError(ex.Message);
155 | }
156 |
157 | return new AuthenticationTicket(null, properties);
158 | }
159 |
160 | protected override Task ApplyResponseChallengeAsync()
161 | {
162 | _logger.WriteVerbose("ApplyResponseChallenge");
163 |
164 | if (Response.StatusCode != 401)
165 | {
166 | return Task.FromResult