Skip to content
This repository was archived by the owner on Apr 10, 2021. It is now read-only.

Commit be9befc

Browse files
committed
Register jwt external provider
1 parent 2ca9403 commit be9befc

File tree

8 files changed

+291
-92
lines changed

8 files changed

+291
-92
lines changed

Plugins/RawCMS.Plugins.Core/AuthPlugin.cs

+134-59
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,30 @@
99
using IdentityModel.AspNetCore.OAuth2Introspection;
1010
using IdentityServer4.AccessTokenValidation;
1111
using IdentityServer4.Services;
12+
using Microsoft.AspNetCore.Authentication.JwtBearer;
13+
using Microsoft.AspNetCore.Authorization;
1214
using Microsoft.AspNetCore.Builder;
1315
using Microsoft.AspNetCore.Identity;
1416
using Microsoft.Extensions.Configuration;
1517
using Microsoft.Extensions.DependencyInjection;
1618
using Microsoft.Extensions.Logging;
1719
using Microsoft.IdentityModel.Logging;
20+
using Newtonsoft.Json;
21+
using Newtonsoft.Json.Linq;
1822
using RawCMS.Library.Core;
1923
using RawCMS.Library.Core.Interfaces;
24+
using RawCMS.Library.Service;
2025
using RawCMS.Plugins.Core.Configuration;
2126
using RawCMS.Plugins.Core.Extensions;
2227
using RawCMS.Plugins.Core.Handlers;
2328
using RawCMS.Plugins.Core.Model;
2429
using RawCMS.Plugins.Core.Stores;
30+
using System;
31+
using System.Collections.Generic;
32+
using System.IdentityModel.Tokens.Jwt;
33+
using System.Linq;
34+
using System.Net.Http;
35+
using System.Net.Http.Headers;
2536
using System.Security.Claims;
2637

2738
namespace RawCMS.Plugins.Core
@@ -45,7 +56,7 @@ public AuthPlugin(AppEngine appEngine, AuthConfig config, ILogger logger) : base
4556
public override void ConfigureServices(IServiceCollection services)
4657
{
4758
IdentityModelEventSource.ShowPII = true;
48-
59+
4960
// all singleton works on CI/docker env but not on local
5061
//services.AddSingleton<IUserStore<IdentityUser>, RawUserStore>();
5162
//services.AddSingleton<IUserPasswordStore<IdentityUser>, RawUserStore>();
@@ -54,7 +65,7 @@ public override void ConfigureServices(IServiceCollection services)
5465
//services.AddSingleton<IPasswordHasher<IdentityUser>, RawUserStore>();
5566
//services.AddSingleton<IProfileService, RawUserStore>();
5667
//services.AddSingleton<IUserClaimsPrincipalFactory<IdentityUser>, RawClaimsFactory>();
57-
68+
5869
// this works on local
5970
services.AddScoped<IUserStore<IdentityUser>, RawUserStore>();
6071
services.AddScoped<IUserPasswordStore<IdentityUser>, RawUserStore>();
@@ -63,8 +74,8 @@ public override void ConfigureServices(IServiceCollection services)
6374
services.AddScoped<IPasswordHasher<IdentityUser>, RawUserStore>();
6475
services.AddScoped<IProfileService, RawUserStore>();
6576
services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>, RawClaimsFactory>();
66-
67-
77+
78+
6879
services.AddScoped<RawRoleStore>();
6980
services.AddScoped<IRoleStore<IdentityRole>, RawRoleStore>();
7081
services.AddIdentity<IdentityUser, IdentityRole>();
@@ -79,68 +90,132 @@ public override void ConfigureServices(IServiceCollection services)
7990
.AddAspNetIdentity<IdentityUser>()
8091
.AddProfileServiceCustom();
8192

82-
if (config.Mode == OAuthMode.External)
93+
//if (config.Mode == OAuthMode.External)
94+
//{
95+
// OAuth2IntrospectionOptions options = new OAuth2IntrospectionOptions
96+
// {
97+
// //base - address of your identityserver
98+
// Authority = config.Authority,
99+
// ClientSecret = config.ClientSecret,
100+
// ClientId = config.ClientId,
101+
// BasicAuthenticationHeaderStyle = IdentityModel.Client.BasicAuthenticationHeaderStyle.Rfc2617
102+
// };
103+
// if (!string.IsNullOrWhiteSpace(config.IntrospectionEndpoint))
104+
// {
105+
// options.IntrospectionEndpoint = config.IntrospectionEndpoint;
106+
// }
107+
// options.TokenTypeHint = "Bearer";
108+
// if (!string.IsNullOrWhiteSpace(config.TokenTypeHint))
109+
// {
110+
// options.TokenTypeHint = config.TokenTypeHint;
111+
// }
112+
113+
// options.Validate();
114+
115+
// services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
116+
// .AddOAuth2Introspection(x =>
117+
// {
118+
// x = options;
119+
// });
120+
//}
121+
//else
122+
//{
123+
124+
//}
125+
126+
var schemeList = new List<string> { "Bearer" };
127+
var authBuilder = services.AddAuthentication();
128+
129+
//rawcms providers
130+
authBuilder = authBuilder.AddScheme<RawIdentityServerAuthenticationOptions, RawLocalAccessTokenValidationHandler>("Bearer", (o) =>
131+
{
132+
o.AdminApiKey = this.config.RawCMSProvider.AdminApiKey;
133+
o.ApiKey = this.config.RawCMSProvider.ApiKey;
134+
});
135+
136+
if(this.config.ExternalProvider != null && this.config.ExternalProvider.Count > 0)
83137
{
84-
OAuth2IntrospectionOptions options = new OAuth2IntrospectionOptions
85-
{
86-
//base - address of your identityserver
87-
Authority = config.Authority,
88-
ClientSecret = config.ClientSecret,
89-
ClientId = config.ClientId,
90-
BasicAuthenticationHeaderStyle = IdentityModel.Client.BasicAuthenticationHeaderStyle.Rfc2617
91-
};
92-
if (!string.IsNullOrWhiteSpace(config.IntrospectionEndpoint))
93-
{
94-
options.IntrospectionEndpoint = config.IntrospectionEndpoint;
95-
}
96-
options.TokenTypeHint = "Bearer";
97-
if (!string.IsNullOrWhiteSpace(config.TokenTypeHint))
138+
var crudService = services.BuildServiceProvider().GetService<CRUDService>();
139+
140+
foreach (var provider in this.config.ExternalProvider)
98141
{
99-
options.TokenTypeHint = config.TokenTypeHint;
142+
//TODO: add multiple authintication schema type
143+
authBuilder = authBuilder.AddJwtProvider(provider, crudService);
144+
schemeList.Add(provider.SchemaName);
100145
}
146+
}
101147

102-
options.Validate();
148+
149+
//.AddJwtBearer("Auth0Bis", x =>
150+
//{
151+
// x.Authority = "https://dev-t61xkx2b.eu.auth0.com";
152+
// x.Audience = "http://localhost:1111";
153+
// x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
154+
// {
155+
// RoleClaimType = "permissions"
156+
// };
157+
// x.Events = new JwtBearerEvents
158+
// {
159+
// OnTokenValidated = async ctx =>
160+
// {
161+
// var accessToken = ctx.SecurityToken as JwtSecurityToken;
162+
// if (accessToken != null)
163+
// {
164+
// var client = new HttpClient();
165+
// var request = new HttpRequestMessage
166+
// {
167+
// Method = HttpMethod.Post,
168+
// RequestUri = new Uri("https://dev-t61xkx2b.eu.auth0.com/userinfo")
169+
// };
170+
// request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken.RawData);
171+
// request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
103172

104-
services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
105-
.AddOAuth2Introspection(x =>
173+
// var message = await client.SendAsync(request);
174+
// if (message.IsSuccessStatusCode)
175+
// {
176+
// var response = await message.Content.ReadAsStringAsync();
177+
// var userInfo = JsonConvert.DeserializeObject<JObject>(response);
178+
// if (ctx.Principal.Identity is ClaimsIdentity identity)
179+
// {
180+
// foreach (var cl in userInfo.Properties())
181+
// {
182+
// if (identity.Claims.Where(y => y.Type == cl.Name).Count() == 0)
183+
// {
184+
// identity.AddClaim(new Claim(cl.Name, cl.Value.Value<string>()));
185+
// }
186+
// }
187+
// string perm = ctx.Principal.FindFirstValue("permissions");
188+
// var claimRole = identity.Claims.Where(y => y.Type == ClaimTypes.Role).FirstOrDefault() ?? new Claim(ClaimTypes.Role, string.Empty);
189+
// identity.AddClaim(new Claim(ClaimTypes.Role, string.Join(',', claimRole.Value, perm)));
190+
// }
191+
// }
192+
// }
193+
// }
194+
// };
195+
196+
// x.Validate();
197+
//})
198+
//.AddScheme<RawIdentityServerAuthenticationOptions, RawLocalAccessTokenValidationHandler>("Bearer", (o) =>
199+
//{
200+
// o.AdminApiKey = this.config.AdminApiKey;
201+
// o.ApiKey = this.config.ApiKey;
202+
//})
203+
// .AddScheme<RawIdentityServerAuthenticationOptions, RawLocalAccessTokenValidationHandler>("ApiKey", (o) =>
204+
// {
205+
// o.AdminApiKey = this.config.AdminApiKey;
206+
// o.ApiKey = this.config.ApiKey;
207+
// });
208+
209+
services.AddAuthorization(options =>
106210
{
107-
x = options;
211+
var policyBuilder = new AuthorizationPolicyBuilder()
212+
.RequireAuthenticatedUser()
213+
.AddAuthenticationSchemes(schemeList.ToArray())
214+
.Build();
215+
216+
options.DefaultPolicy = policyBuilder;
217+
options.AddPolicy("rawCms", policyBuilder);
108218
});
109-
}
110-
else
111-
{
112-
services
113-
.AddAuthentication((options) =>
114-
{
115-
options.DefaultScheme = "Bearer";
116-
options.DefaultChallengeScheme = "Bearer";
117-
//options.AddScheme("ApiKey", (x) => { x.HandlerType = typeof(RawLocalAccessTokenValidationHandler); });
118-
})
119-
.AddJwtBearer("Bearer" + IdentityServerAuthenticationDefaults.AuthenticationScheme, (options) =>
120-
{
121-
options.RequireHttpsMetadata = false;
122-
options.SaveToken = true;
123-
options.IncludeErrorDetails = true;
124-
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
125-
{
126-
RoleClaimType = ClaimTypes.Role,
127-
NameClaimType = ClaimTypes.NameIdentifier
128-
};
129-
//options.Audience = IdentityServer4.IdentityServerConstants.LocalIdentityProvider;
130-
//options.Authority = IdentityServer4.IdentityServerConstants.LocalIdentityProvider;
131-
options.Validate();
132-
})
133-
.AddScheme<RawIdentityServerAuthenticationOptions, RawLocalAccessTokenValidationHandler>("Bearer", (o) =>
134-
{
135-
o.AdminApiKey = this.config.AdminApiKey;
136-
o.ApiKey = this.config.ApiKey;
137-
})
138-
.AddScheme<RawIdentityServerAuthenticationOptions, RawLocalAccessTokenValidationHandler>("ApiKey", (o) =>
139-
{
140-
o.AdminApiKey = this.config.AdminApiKey;
141-
o.ApiKey = this.config.ApiKey;
142-
});
143-
}
144219
}
145220

146221
public override void Configure(IApplicationBuilder app)

Plugins/RawCMS.Plugins.Core/Configuration/AuthConfig.cs

+31-21
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,44 @@ namespace RawCMS.Plugins.Core.Configuration
1515
{
1616
public enum OAuthMode
1717
{
18-
Standalone,
19-
External
18+
JWT,
19+
Introspection
2020
}
2121

22-
public class AuthConfig
22+
public class ExternalProvider
2323
{
24-
public AuthConfig()
25-
{
26-
Mode = OAuthMode.Standalone;
27-
Authority = "http://localhost:50093";
28-
ClientId = "raw.client";
29-
ClientSecret = "raw.secret";
30-
ApiResource = "rawcms";
31-
}
32-
3324
public OAuthMode Mode { get; set; }
25+
public string SchemaName { get; set; }
26+
public string Authority { get; set; }
27+
public string Audience { get; set; }
28+
public string UserInfoEndpoint { get; set; }
29+
public string RoleClaimType { get; set; }
30+
}
3431

32+
public class RawCMSProvider
33+
{
34+
public string Authority { get; set; }
3535
public string ClientId { get; set; }
3636
public string ClientSecret { get; set; }
3737
public string ApiResource { get; set; }
38-
public string Authority { get; set; }
39-
public string IntrospectionEndpoint { get; internal set; }
40-
public string TokenTypeHint { get; internal set; }
41-
42-
public bool OauthEnabled { get; set; }
4338

4439
public string AdminApiKey { get; set; }
4540
public string ApiKey { get; set; }
41+
}
42+
43+
public class AuthConfig
44+
{
45+
public AuthConfig()
46+
{
47+
RawCMSProvider.Authority = "http://localhost:50093";
48+
RawCMSProvider.ClientId = "raw.client";
49+
RawCMSProvider.ClientSecret = "raw.secret";
50+
RawCMSProvider.ApiResource = "rawcms";
51+
}
52+
53+
public RawCMSProvider RawCMSProvider { get; set; } = new RawCMSProvider();
54+
public List<ExternalProvider> ExternalProvider { get; set; } = new List<ExternalProvider>();
55+
4656

4757
// scopes define the resources in your system
4858
public IEnumerable<IdentityResource> GetIdentityResources()
@@ -59,11 +69,11 @@ public IEnumerable<ApiResource> GetApiResources()
5969
{
6070
return new List<ApiResource>
6171
{
62-
new ApiResource(ApiResource, ApiResource)
72+
new ApiResource(RawCMSProvider.ApiResource, RawCMSProvider.ApiResource)
6373
{
6474
ApiSecrets = new List<Secret>
6575
{
66-
new Secret(ClientSecret.Sha256())
76+
new Secret(RawCMSProvider.ClientSecret.Sha256())
6777
},
6878
Scopes=
6979
{
@@ -82,14 +92,14 @@ public IEnumerable<Client> GetClients()
8292
{
8393
new Client
8494
{
85-
ClientId = ClientId,
95+
ClientId = RawCMSProvider.ClientId,
8696
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
8797
AlwaysIncludeUserClaimsInIdToken = true,
8898
AlwaysSendClientClaims = true,
8999

90100
ClientSecrets =
91101
{
92-
new Secret(ClientSecret.Sha256())
102+
new Secret(RawCMSProvider.ClientSecret.Sha256())
93103
},
94104
AllowedScopes =
95105
{

Plugins/RawCMS.Plugins.Core/Controllers/admin/AdminController.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414

1515
namespace RawCMS.Plugins.Core.Controllers.Controllers.admin
1616
{
17-
[Authorize(AuthenticationSchemes = "Bearer")]
18-
[Authorize(Roles = "Admin", AuthenticationSchemes = "Bearer,ApiKey")]
17+
//[Authorize(AuthenticationSchemes = "Bearer")]
18+
//[Authorize(Roles = "Admin", AuthenticationSchemes = "Bearer,ApiKey")]
19+
[Authorize(Roles = "Admin")]
1920
[Route("system/[controller]")]
2021
[ParameterValidator("collection", "_(.*)", false)]
2122
public class AdminController : CRUDController

Plugins/RawCMS.Plugins.Core/Data/UserPresaveLambda.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public override void Execute(string collection, ref JObject item, ref Dictionary
3030
{
3131
item["NormalizedUserName"] = RawUserStore.NormalizeString(item["UserName"].Value<string>());
3232
}
33-
if (item.ContainsKey("NormalizedEmail"))
33+
if (item.ContainsKey("Email"))
3434
{
35-
item["NormalizedEmail"] = RawUserStore.NormalizeString(item["NormalizedEmail"].Value<string>());
35+
item["NormalizedEmail"] = RawUserStore.NormalizeString(item["Email"].Value<string>());
3636
}
3737
if (item.ContainsKey("NewPassword"))
3838
{

0 commit comments

Comments
 (0)