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