mirror of https://github.com/abpframework/abp.git
21 changed files with 385 additions and 15 deletions
@ -0,0 +1,12 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="IdentityModel" Version="2.16.1" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using IdentityModel.Client; |
|||
using Newtonsoft.Json.Linq; |
|||
|
|||
namespace AbpDesk.ConsoleClient |
|||
{ |
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
RunDemo().Wait(); |
|||
Console.ReadLine(); |
|||
} |
|||
|
|||
private static async Task RunDemo() |
|||
{ |
|||
// discover endpoints from metadata
|
|||
var disco = await DiscoveryClient.GetAsync("http://localhost:59980"); |
|||
if (disco.IsError) |
|||
{ |
|||
Console.WriteLine(disco.Error); |
|||
return; |
|||
} |
|||
|
|||
// request token
|
|||
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret"); |
|||
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1"); |
|||
|
|||
if (tokenResponse.IsError) |
|||
{ |
|||
Console.WriteLine(tokenResponse.Error); |
|||
return; |
|||
} |
|||
|
|||
Console.WriteLine(tokenResponse.Json); |
|||
|
|||
// call api
|
|||
var client = new HttpClient(); |
|||
client.SetBearerToken(tokenResponse.AccessToken); |
|||
|
|||
var response = await client.GetAsync("http://localhost:59980/identity-test"); |
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
Console.WriteLine(response.StatusCode); |
|||
} |
|||
else |
|||
{ |
|||
var content = await response.Content.ReadAsStringAsync(); |
|||
Console.WriteLine(content); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace AbpDesk.Web.Mvc.Controllers |
|||
{ |
|||
[Route("identity-test")] |
|||
[Authorize] |
|||
public class IdentityTestController : AbpController |
|||
{ |
|||
[HttpGet] |
|||
public IActionResult Get() |
|||
{ |
|||
return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
{"KeyId":"3b003a0fc7d8278f13f59d44f4620374","Parameters":{"D":"Qravv6bNhcfweciZna68hlflA8ygXVgoycYFC/oSG0Ulxr7iN1WtpJEau80OReBKVuRqqvxepzJcNv9CqMGvs9+bDrymk9DDdH46ybFKZB2MaufaBuwbuiJi5qCsGmaDvjzf1dwPyGS+7OEa28GDw7ibwwkf6sMJcIBWGQrAZ6O+/Ka8ouF8Zdn+6Igv4rK+RVtKQbjYeJ9CvhOZFXSuLl1XVAM01bGwvQSh8BwMC7i1g7gKypvTG31OSlG3ZzIoF7uuoXaC/WWbGvryvPUzFbgCLO8tQu4/Kdy9NsU3C3M/adUtRxLtVNvD29o8dDZT8NM2UTotfgGg3v72ktmnjQ==","DP":"cQ4XqOgPQAOO4dqg3yFH/xFoXQx/5/q4oGtFZYDTSOyrRL/LopZHrr53ys7Uble7+dDa6PPYBgY/C2/SwLBaUF9FpM27Kp7D+3yUKFbKtW8uke+UEM6MgcfjBdwEFVV4CqqHzgD8JvtZ1xhBvx6yUJuHcxxuWKlElXhsTVJKwwE=","DQ":"ktpqqgnwT2Rr9Eb0Kkyg5LZgsO75Pu+0u1q4WhZ7ZzOMJqquCf7hw7ucaWPLq8Ipzn5Hu5CO2gT+URjMGkJNQA+728tFnFkST9wFeqp1hQh5ZxgYsONiH9e/Nw6iauI07i2TYt7pFhIYUOg52/SvHrAzPyEYznCw3BZrR4rEjJk=","Exponent":"AQAB","InverseQ":"hkiDiH926FhARZnVhV5sDnbjxGTdQl8ErZ+qOdBE2vVP6IwNj14dkw+ON4XeIyM/CE3RYmhd8I68JCDNVd6J4hE4NIe4xr+ykmVHYLWQhZ/k4QippwabZ3SK9dkcosQF6BP3lNSgW0UxomdgMKQcsQqccroKEq52Ccr3dUVXICg=","Modulus":"7fgl4D1Emkq+KRAj+u7g7e8hrEhYT19ZRVu1LVdZpx8vDUmuBLVCrNdm6VPIeV5YvrRLELiAknujOMytnIwtY6D1beOtdunEE1z32QsFxizYa9lVaL1rwEURnLQ51sP2bJsxNZnHaJQFGCzOc1i8V551V8eG43asoSbQKFz8Aa6A5UdZaecWSF9WoIkWH/xdi2Ecun69HAS8LiS2S3yKgqyLJivZM72lMUgTWyklh8WMscMb2pRTHspV2oqlIRBo4bRbLgYRJ+6pOMvtge5CgWMupolpy0BTpQrRLPYK9oiZ9iP1/Hdrlu8U0G6XL1rz0kkfqOU10AtlYZe01b0zXQ==","P":"+pWvk2Q5+YN0IikHJkCdpeZMUM3Tkj08FEJETRNU3Rcrpg1wyFQJdqIib28XzWdua5vilBNnAwhbBw4dO978rn1riHq8VQD1JSFh1+vwlzhG76M89KnP7v/DuILbTT4tKU28VWjQsT4RVlI5Rqc3REaUoQDYAmvARCFDGOxCrYs=","Q":"8xyreLJWnAFQoVJjLhK/eNE+GdABidksHz47k1p9imeKAv4xpFx4jfAec4VSiXCvK/KW9+fbPA+S4hEa/5oICKvvALFZavL7A4htnQjflgnEc+QqlR7TjnVgMILyBB3mf4mlNjR7kfwcDwGLRBjMx8mxadj+NlREri4Jw6q4D7c="}} |
|||
@ -0,0 +1,19 @@ |
|||
using System.IdentityModel.Tokens.Jwt; |
|||
|
|||
namespace Volo.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Updates <see cref="JwtSecurityTokenHandler.DefaultInboundClaimTypeMap"/> to be compatible with identity server claims.
|
|||
/// Default: true.
|
|||
/// </summary>
|
|||
public bool UpdateJwtSecurityTokenHandlerDefaultInboundClaimTypeMap { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// Updates <see cref="AbpClaimTypes"/> to be compatible with identity server claims.
|
|||
/// Default: true.
|
|||
/// </summary>
|
|||
public bool UpdateAbpClaimTypes { get; set; } = true; |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.IdentityModel.Tokens.Jwt; |
|||
using IdentityModel; |
|||
using IdentityServer4.Services; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.IdentityServer.AspNetIdentity; |
|||
using Volo.Abp.Security.Claims; |
|||
|
|||
namespace Volo.Abp.IdentityServer |
|||
{ |
|||
public static class AbpZeroIdentityServerBuilderExtensions |
|||
{ |
|||
public static IIdentityServerBuilder AddAbpIdentityServer( |
|||
this IIdentityServerBuilder builder, |
|||
Action<AbpIdentityServerOptions> optionsAction = null) |
|||
{ |
|||
var options = new AbpIdentityServerOptions(); |
|||
optionsAction?.Invoke(options); |
|||
|
|||
//TODO: AspNet Identity integration lines. Can be extracted to a extension method
|
|||
builder.AddAspNetIdentity<IdentityUser>(); |
|||
builder.AddProfileService<AbpProfileService>(); |
|||
builder.AddResourceOwnerValidator<AbpResourceOwnerPasswordValidator>(); |
|||
|
|||
builder.Services.Replace(ServiceDescriptor.Transient<IClaimsService, AbpClaimsService>()); |
|||
|
|||
if (options.UpdateAbpClaimTypes) |
|||
{ |
|||
AbpClaimTypes.UserId = JwtClaimTypes.Subject; |
|||
AbpClaimTypes.UserName = JwtClaimTypes.Name; |
|||
AbpClaimTypes.Role = JwtClaimTypes.Role; |
|||
} |
|||
|
|||
if (options.UpdateJwtSecurityTokenHandlerDefaultInboundClaimTypeMap) |
|||
{ |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap[AbpClaimTypes.UserId] = AbpClaimTypes.UserId; |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap[AbpClaimTypes.UserName] = AbpClaimTypes.UserName; |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap[AbpClaimTypes.Role] = AbpClaimTypes.Role; |
|||
} |
|||
|
|||
return builder; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using IdentityServer4.Services; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace Volo.Abp.IdentityServer.AspNetIdentity |
|||
{ |
|||
public class AbpClaimsService : DefaultClaimsService |
|||
{ |
|||
public AbpClaimsService(IProfileService profile, ILogger<DefaultClaimsService> logger) |
|||
: base(profile, logger) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System.Threading.Tasks; |
|||
using IdentityServer4.AspNetIdentity; |
|||
using IdentityServer4.Models; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.IdentityServer.AspNetIdentity |
|||
{ |
|||
//TODO: Implement multi-tenancy as like in old ABP
|
|||
|
|||
public class AbpProfileService : ProfileService<IdentityUser> |
|||
{ |
|||
public AbpProfileService( |
|||
IdentityUserManager userManager, |
|||
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory |
|||
) : base(userManager, claimsFactory) |
|||
{ |
|||
|
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task GetProfileDataAsync(ProfileDataRequestContext context) |
|||
{ |
|||
await base.GetProfileDataAsync(context); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task IsActiveAsync(IsActiveContext context) |
|||
{ |
|||
await base.IsActiveAsync(context); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System.Threading.Tasks; |
|||
using IdentityServer4.AspNetIdentity; |
|||
using IdentityServer4.Services; |
|||
using IdentityServer4.Validation; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.IdentityServer.AspNetIdentity |
|||
{ |
|||
public class AbpResourceOwnerPasswordValidator : ResourceOwnerPasswordValidator<IdentityUser> |
|||
{ |
|||
public AbpResourceOwnerPasswordValidator( |
|||
IdentityUserManager userManager, |
|||
SignInManager<IdentityUser> signInManager, |
|||
IEventService events, |
|||
ILogger<ResourceOwnerPasswordValidator<IdentityUser>> logger |
|||
) : base( |
|||
userManager, |
|||
signInManager, |
|||
events, |
|||
logger) |
|||
{ |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) |
|||
{ |
|||
await base.ValidateAsync(context); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Builder; |
|||
|
|||
namespace Volo.Abp.IdentityServer.Jwt |
|||
{ |
|||
//TODO: Can we move this to another package..?
|
|||
|
|||
public static class JwtTokenMiddleware |
|||
{ |
|||
public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string schema) |
|||
{ |
|||
return app.Use(async (ctx, next) => |
|||
{ |
|||
if (ctx.User.Identity?.IsAuthenticated != true) |
|||
{ |
|||
var result = await ctx.AuthenticateAsync(schema); |
|||
if (result.Succeeded && result.Principal != null) |
|||
{ |
|||
ctx.User = result.Principal; |
|||
} |
|||
} |
|||
|
|||
await next(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System.Collections.Generic; |
|||
using IdentityServer4.Models; |
|||
|
|||
namespace Volo.Abp.IdentityServer.Temp |
|||
{ |
|||
internal static class IdentityServerConfig |
|||
{ |
|||
public static IEnumerable<ApiResource> GetApiResources() |
|||
{ |
|||
return new List<ApiResource> |
|||
{ |
|||
new ApiResource("api1", "My API") |
|||
}; |
|||
} |
|||
|
|||
public static IEnumerable<IdentityServer4.Models.Client> GetClients() |
|||
{ |
|||
return new List<Client> |
|||
{ |
|||
new Client |
|||
{ |
|||
ClientId = "client", |
|||
|
|||
// no interactive user, use the clientid/secret for authentication
|
|||
AllowedGrantTypes = GrantTypes.ClientCredentials, |
|||
|
|||
// secret for authentication
|
|||
ClientSecrets = |
|||
{ |
|||
new IdentityServer4.Models.Secret("secret".Sha256()) |
|||
}, |
|||
|
|||
// scopes that client has access to
|
|||
AllowedScopes = { "api1" } |
|||
} |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Design; |
|||
|
|||
namespace Volo.Abp.IdentityServer.EntityFrameworkCore |
|||
{ |
|||
/* This class is needed for EF Core command line tooling */ |
|||
|
|||
public class IdentityServerDbContextFactory : IDesignTimeDbContextFactory<IdentityServerDbContext> |
|||
{ |
|||
public IdentityServerDbContext CreateDbContext(string[] args) |
|||
{ |
|||
var builder = new DbContextOptionsBuilder<IdentityServerDbContext>(); |
|||
builder.UseSqlServer("Server=localhost;Database=AbpDesk;Trusted_Connection=True;"); |
|||
return new IdentityServerDbContext(builder.Options); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue