Integration with inhouse identity server

master
Tudor Stanciu 2020-12-21 01:21:21 +02:00
parent e3ce6fc694
commit c89e07d146
13 changed files with 28 additions and 155 deletions

View File

@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Authentication; using IdentityServer.PublishedLanguage.Dto;
using IdentityServer.Wrapper.Services;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NetworkResurrector.Application.Services;
using NetworkResurrector.Domain.Entities;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
@ -12,12 +12,12 @@ namespace NetworkResurrector.Api.Authentication
{ {
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{ {
private readonly IUserService _userService; private readonly IIdentityService _identityService;
public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserService userService) public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IIdentityService identityService)
: base(options, logger, encoder, clock) : base(options, logger, encoder, clock)
{ {
_userService = userService; _identityService = identityService;
} }
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
@ -30,7 +30,7 @@ namespace NetworkResurrector.Api.Authentication
{ {
var authorizationHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); var authorizationHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
var token = authorizationHeader.Parameter; var token = authorizationHeader.Parameter;
user = await _userService.Authenticate(token); user = await _identityService.Authorize(token);
} }
catch catch
{ {

View File

@ -2,7 +2,6 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NetworkResurrector.Application.Commands; using NetworkResurrector.Application.Commands;
using NetworkResurrector.Application.Queries;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NetworkResurrector.Api.Controllers namespace NetworkResurrector.Api.Controllers
@ -19,20 +18,6 @@ namespace NetworkResurrector.Api.Controllers
_mediator = mediator; _mediator = mediator;
} }
[AllowAnonymous]
[HttpGet("token/{userName}/{password}")]
public async Task<IActionResult> GetToken([FromRoute] GetToken.Query query)
{
var result = await _mediator.Send(query);
return Ok(result);
}
[HttpGet("validate-token")]
public IActionResult ValidateToken()
{
return Ok("Valid");
}
[HttpPost("wake")] [HttpPost("wake")]
public async Task<IActionResult> WakeMachine([FromBody] WakeMachine wakeMachine) public async Task<IActionResult> WakeMachine([FromBody] WakeMachine wakeMachine)
{ {

View File

@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="IdentityServer.Wrapper" Version="1.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsPackageVersion)" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsPackageVersion)" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsPackageVersion)" />

View File

@ -1,4 +1,5 @@
using AutoMapper; using AutoMapper;
using IdentityServer.Wrapper;
using MediatR; using MediatR;
using MediatR.Pipeline; using MediatR.Pipeline;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
@ -44,6 +45,9 @@ namespace NetworkResurrector.Api
services.AddAutoMapper( services.AddAutoMapper(
typeof(Application.Mappings.MappingProfile).Assembly); typeof(Application.Mappings.MappingProfile).Assembly);
// Identity server
services.UseIdentityServices(_configuration.GetSection("IdentityServer")["BaseAddress"]);
// Swagger // Swagger
services.AddSwagger("NetworkResurrector API"); services.AddSwagger("NetworkResurrector API");
@ -80,7 +84,7 @@ namespace NetworkResurrector.Api
private Assembly[] GetMediatRAssemblies() private Assembly[] GetMediatRAssemblies()
{ {
var assembly = typeof(Application.Queries.GetToken).Assembly; var assembly = typeof(Application.Commands.WakeMachine).Assembly;
return new Assembly[] { assembly }; return new Assembly[] { assembly };
} }
} }

View File

@ -11,20 +11,14 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Users": [ "IdentityServer": {
{ "BaseAddress": "http://localhost:5063/"
"UserId": 1, },
"UserName": "***REMOVED***",
"Password": "***REMOVED***"
}
],
"WakeOnLan": { "WakeOnLan": {
"Provider": { "Provider": {
"Use": "Inhouse", "Use": "Inhouse",
"Options": [ "Inhouse", "Nikeee" ] "Options": [ "Inhouse", "Nikeee" ]
} }
}, },
"Shutdown": { "Shutdown": { }
}
} }

View File

@ -10,7 +10,6 @@ namespace NetworkResurrector.Application
public static void AddApplicationServices(this IServiceCollection services) public static void AddApplicationServices(this IServiceCollection services)
{ {
services.AddSingleton<IParamProvider, ParamProvider>(); services.AddSingleton<IParamProvider, ParamProvider>();
services.AddScoped<IUserService, UserService>();
services.AddStores(); services.AddStores();
services.AddSingleton<IValidationService, ValidationService>(); services.AddSingleton<IValidationService, ValidationService>();
services.AddSingleton<IPingService, PingService>(); services.AddSingleton<IPingService, PingService>();

View File

@ -1,6 +1,4 @@
using AutoMapper; using AutoMapper;
using NetworkResurrector.Application.Queries;
using NetworkResurrector.Domain.Models;
namespace NetworkResurrector.Application.Mappings namespace NetworkResurrector.Application.Mappings
{ {
@ -8,7 +6,7 @@ namespace NetworkResurrector.Application.Mappings
{ {
public MappingProfile() public MappingProfile()
{ {
CreateMap<SecurityToken, GetToken.Model>(); // Add mappings here
} }
} }
} }

View File

@ -0,0 +1,7 @@
namespace NetworkResurrector.Application.Queries
{
class GetServiceVersion
{
//TO DO
}
}

View File

@ -1,48 +0,0 @@
using AutoMapper;
using MediatR;
using NDB.Application.DataContracts;
using NetworkResurrector.Application.Services;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace NetworkResurrector.Application.Queries
{
public class GetToken
{
public class Query : Query<Model>
{
public string UserName { get; set; }
public string Password { get; set; }
public Query() { }
}
public class Model
{
public string Token { get; set; }
public DateTime ValidUntil { get; set; }
}
public class QueryHandler : IRequestHandler<Query, Model>
{
private readonly IUserService _userService;
private readonly IMapper _mapper;
public QueryHandler(IUserService userService, IMapper mapper)
{
_userService = userService;
_mapper = mapper;
}
public async Task<Model> Handle(Query request, CancellationToken cancellationToken)
{
var securityToken = await _userService.Login(request.UserName, request.Password);
if (securityToken == null)
return null;
var result = _mapper.Map<Model>(securityToken);
return result;
}
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using NetworkResurrector.Domain.Entities;
using NetworkResurrector.Domain.Services; using NetworkResurrector.Domain.Services;
namespace NetworkResurrector.Application.Services namespace NetworkResurrector.Application.Services
@ -13,6 +12,6 @@ namespace NetworkResurrector.Application.Services
_configuration = configuration; _configuration = configuration;
} }
public User[] Users => _configuration.GetSection("Users").Get<User[]>(); // public User[] Users => _configuration.GetSection("Users").Get<User[]>();
} }
} }

View File

@ -1,54 +0,0 @@
using NetworkResurrector.Application.Stores;
using NetworkResurrector.Domain.Entities;
using NetworkResurrector.Domain.Models;
using NetworkResurrector.Domain.Services;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace NetworkResurrector.Application.Services
{
public interface IUserService
{
Task<SecurityToken> Login(string userName, string password);
Task<User> Authenticate(string token);
}
public class UserService : IUserService
{
private readonly IParamProvider _paramProvider;
private readonly ISecurityStore _securityStore;
public UserService(IParamProvider paramProvider, ISecurityStore securityStore)
{
_paramProvider = paramProvider;
_securityStore = securityStore;
}
public async Task<SecurityToken> Login(string userName, string password)
{
var user = _paramProvider.Users.FirstOrDefault(z => z.UserName == userName && z.Password == password);
if (user == null)
return null;
var token = $"{Guid.NewGuid()}-{Guid.NewGuid()}-{user.UserId}";
await Task.Run(() =>_securityStore.SetToken(token, user.UserId));
var securityToken = new SecurityToken() { UserId = user.UserId, Token = token };
return securityToken;
}
public async Task<User> Authenticate(string token)
{
var tokenValidation = await Task.Run(() => _securityStore.ValidateToken(token));
if (tokenValidation.Success)
{
var user = _paramProvider.Users.FirstOrDefault(z => z.UserId == tokenValidation.UserId);
if (user != null)
return user;
}
return null;
}
}
}

View File

@ -1,9 +0,0 @@
namespace NetworkResurrector.Domain.Entities
{
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@ -1,9 +1,6 @@
using NetworkResurrector.Domain.Entities; namespace NetworkResurrector.Domain.Services
namespace NetworkResurrector.Domain.Services
{ {
public interface IParamProvider public interface IParamProvider
{ {
User[] Users { get; }
} }
} }