mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 05:13:18 -07:00
Fixed some issues around the identity
This commit is contained in:
parent
cf6b5c5138
commit
8e04061e4e
24 changed files with 269 additions and 57 deletions
|
@ -1,14 +1,14 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Core.Models;
|
||||||
|
|
||||||
namespace Ombi.Core.IdentityResolver
|
namespace Ombi.Core.IdentityResolver
|
||||||
{
|
{
|
||||||
public interface IUserIdentityManager
|
public interface IUserIdentityManager
|
||||||
{
|
{
|
||||||
Task CreateUser(User user);
|
Task CreateUser(UserDto user);
|
||||||
Task<bool> CredentialsValid(string username, string password);
|
Task<bool> CredentialsValid(string username, string password);
|
||||||
Task<User> GetUser(string username);
|
Task<UserDto> GetUser(string username);
|
||||||
Task<IEnumerable<User>> GetUsers();
|
Task<IEnumerable<UserDto>> GetUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,7 +29,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||||
|
using Ombi.Core.Models;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
|
||||||
|
@ -37,38 +39,43 @@ namespace Ombi.Core.IdentityResolver
|
||||||
{
|
{
|
||||||
public class UserIdentityManager : IUserIdentityManager
|
public class UserIdentityManager : IUserIdentityManager
|
||||||
{
|
{
|
||||||
public UserIdentityManager(IUserRepository userRepository)
|
public UserIdentityManager(IUserRepository userRepository, IMapper mapper)
|
||||||
{
|
{
|
||||||
UserRepository = userRepository;
|
UserRepository = userRepository;
|
||||||
|
Mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IMapper Mapper { get; }
|
||||||
private IUserRepository UserRepository { get; }
|
private IUserRepository UserRepository { get; }
|
||||||
|
|
||||||
public async Task<bool> CredentialsValid(string username, string password)
|
public async Task<bool> CredentialsValid(string username, string password)
|
||||||
{
|
{
|
||||||
var user = await UserRepository.GetUser(username);
|
var user = await UserRepository.GetUser(username);
|
||||||
var hashedPass = HashPassword(password);
|
var hash = HashPassword(password, user.Salt);
|
||||||
|
|
||||||
return hashedPass.Equals(user.Password);
|
return hash.HashedPass.Equals(user.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<User> GetUser(string username)
|
public async Task<UserDto> GetUser(string username)
|
||||||
{
|
{
|
||||||
return await UserRepository.GetUser(username);
|
return Mapper.Map<UserDto>(await UserRepository.GetUser(username));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<User>> GetUsers()
|
public async Task<IEnumerable<UserDto>> GetUsers()
|
||||||
{
|
{
|
||||||
return await UserRepository.GetUsers();
|
return Mapper.Map<List<UserDto>>(await UserRepository.GetUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateUser(User user)
|
public async Task CreateUser(UserDto userDto)
|
||||||
{
|
{
|
||||||
user.Password = HashPassword(user.Password);
|
var user = Mapper.Map<User>(userDto);
|
||||||
|
var result = HashPassword(user.Password);
|
||||||
|
user.Password = result.HashedPass;
|
||||||
|
user.Salt = result.Salt;
|
||||||
await UserRepository.CreateUser(user);
|
await UserRepository.CreateUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string HashPassword(string password)
|
private UserHash HashPassword(string password)
|
||||||
{
|
{
|
||||||
// generate a 128-bit salt using a secure PRNG
|
// generate a 128-bit salt using a secure PRNG
|
||||||
byte[] salt = new byte[128 / 8];
|
byte[] salt = new byte[128 / 8];
|
||||||
|
@ -76,6 +83,12 @@ namespace Ombi.Core.IdentityResolver
|
||||||
{
|
{
|
||||||
rng.GetBytes(salt);
|
rng.GetBytes(salt);
|
||||||
}
|
}
|
||||||
|
return HashPassword(password, salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private UserHash HashPassword(string password, byte[] salt)
|
||||||
|
{
|
||||||
// derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
|
// derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
|
||||||
var hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
var hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -84,7 +97,13 @@ namespace Ombi.Core.IdentityResolver
|
||||||
iterationCount: 10000,
|
iterationCount: 10000,
|
||||||
numBytesRequested: 256 / 8));
|
numBytesRequested: 256 / 8));
|
||||||
|
|
||||||
return hashed;
|
return new UserHash { HashedPass = hashed, Salt = salt };
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserHash
|
||||||
|
{
|
||||||
|
public string HashedPass { get; set; }
|
||||||
|
public byte[] Salt { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
23
Ombi/Ombi.Core/Models/UserDto.cs
Normal file
23
Ombi/Ombi.Core/Models/UserDto.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Models
|
||||||
|
{
|
||||||
|
public class UserDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Username { get; set; }
|
||||||
|
public string Alias { get; set; }
|
||||||
|
public List<Claim> Claims { get; set; }
|
||||||
|
public string EmailAddress { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
public byte[] Salt { get; set; }
|
||||||
|
public UserType UserType { get; set; }
|
||||||
|
}
|
||||||
|
public enum UserType
|
||||||
|
{
|
||||||
|
LocalUser = 1,
|
||||||
|
PlexUser = 2,
|
||||||
|
EmbyUser = 3,
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="6.0.2" />
|
||||||
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace Ombi.DependencyInjection
|
||||||
services.RegisterApi();
|
services.RegisterApi();
|
||||||
services.RegisterServices();
|
services.RegisterServices();
|
||||||
services.RegisterStore();
|
services.RegisterStore();
|
||||||
|
services.RegisterIdentity();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +57,7 @@ namespace Ombi.DependencyInjection
|
||||||
public static IServiceCollection RegisterServices(this IServiceCollection services)
|
public static IServiceCollection RegisterServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddTransient<IRequestService, JsonRequestService>();
|
services.AddTransient<IRequestService, JsonRequestService>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IdentityServer4" Version="1.4.2" />
|
|
||||||
<PackageReference Include="IdentityServer4.EntityFramework" Version="1.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
33
Ombi/Ombi.Helpers/ClaimConverter.cs
Normal file
33
Ombi/Ombi.Helpers/ClaimConverter.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Ombi.Helpers
|
||||||
|
{
|
||||||
|
public class ClaimConverter : JsonConverter
|
||||||
|
{
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return (objectType == typeof(Claim));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
JObject jo = JObject.Load(reader);
|
||||||
|
string type = (string)jo["Type"];
|
||||||
|
string value = (string)jo["Value"];
|
||||||
|
string valueType = (string)jo["ValueType"];
|
||||||
|
string issuer = (string)jo["Issuer"];
|
||||||
|
string originalIssuer = (string)jo["OriginalIssuer"];
|
||||||
|
return new Claim(type, value, valueType, issuer, originalIssuer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,4 +8,13 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.IdentityModel">
|
||||||
|
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.IdentityModel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Claims">
|
||||||
|
<HintPath>..\..\..\..\..\.nuget\packages\system.security.claims\4.3.0\ref\netstandard1.3\System.Security.Claims.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
19
Ombi/Ombi.Mapping.Maps/Ombi.Mapping.Maps.csproj
Normal file
19
Ombi/Ombi.Mapping.Maps/Ombi.Mapping.Maps.csproj
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard1.6</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="6.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi\Ombi.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
15
Ombi/Ombi.Mapping.Maps/OmbiProfile.cs
Normal file
15
Ombi/Ombi.Mapping.Maps/OmbiProfile.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace Ombi.Mapping.Maps
|
||||||
|
{
|
||||||
|
public class OmbiProfile : Profile
|
||||||
|
{
|
||||||
|
public OmbiProfile()
|
||||||
|
{
|
||||||
|
// Add as many of these lines as you need to map your objects
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
Ombi/Ombi.Mapping/AutoMapperProfile.cs
Normal file
20
Ombi/Ombi.Mapping/AutoMapperProfile.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Ombi.Mapping
|
||||||
|
{
|
||||||
|
public static class AutoMapperProfile
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddOmbiMappingProfile(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
var config = new AutoMapper.MapperConfiguration(cfg =>
|
||||||
|
{
|
||||||
|
cfg.AddProfile(new OmbiProfile());
|
||||||
|
});
|
||||||
|
|
||||||
|
var mapper = config.CreateMapper();
|
||||||
|
services.AddSingleton(mapper);
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Ombi/Ombi.Mapping/Ombi.Mapping.csproj
Normal file
19
Ombi/Ombi.Mapping/Ombi.Mapping.csproj
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard1.6</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="6.0.2" />
|
||||||
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
15
Ombi/Ombi.Mapping/OmbiProfile.cs
Normal file
15
Ombi/Ombi.Mapping/OmbiProfile.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using AutoMapper;
|
||||||
|
using Ombi.Core.Models;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
|
namespace Ombi.Mapping
|
||||||
|
{
|
||||||
|
public class OmbiProfile : Profile
|
||||||
|
{
|
||||||
|
public OmbiProfile()
|
||||||
|
{
|
||||||
|
CreateMap<User, UserDto>().ReverseMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,12 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
|
||||||
|
|
||||||
namespace Ombi.Store.Entities
|
namespace Ombi.Store.Entities
|
||||||
{
|
{
|
||||||
|
@ -33,10 +38,17 @@ namespace Ombi.Store.Entities
|
||||||
{
|
{
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
public Claim[] Claims { get; set; }
|
public string ClaimsSerialized { get; set; }
|
||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
public byte[] Salt { get; set; }
|
||||||
public UserType UserType { get; set; }
|
public UserType UserType { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public List<Claim> Claims {
|
||||||
|
get => JsonConvert.DeserializeObject<List<Claim>>(ClaimsSerialized, new ClaimConverter());
|
||||||
|
set => ClaimsSerialized = JsonConvert.SerializeObject(value, new ClaimConverter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UserType
|
public enum UserType
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IdentityServer4.EntityFramework" Version="1.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
||||||
|
@ -15,4 +14,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26228.10
|
VisualStudioVersion = 15.0.26403.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -26,6 +26,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Store", "Ombi.Store\Om
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Mapping", "Ombi.Mapping\Ombi.Mapping.csproj", "{63E63511-1C7F-4162-8F92-8F7391B3C8A3}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mappers", "Mappers", "{025FB189-2FFB-4F43-A64B-6F1B5A0D2065}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DI", "DI", "{410F36CF-9C60-428A-B191-6FD90610991A}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -60,6 +66,10 @@ Global
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{63E63511-1C7F-4162-8F92-8F7391B3C8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{63E63511-1C7F-4162-8F92-8F7391B3C8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{63E63511-1C7F-4162-8F92-8F7391B3C8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{63E63511-1C7F-4162-8F92-8F7391B3C8A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -67,5 +77,7 @@ Global
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{132DA282-5894-4570-8916-D8C18ED2CE84} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
{EA31F915-31F9-4318-B521-1500CDF40DDF} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{EA31F915-31F9-4318-B521-1500CDF40DDF} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
|
{B39E4558-C557-48E7-AA74-19C5CD809617} = {410F36CF-9C60-428A-B191-6FD90610991A}
|
||||||
|
{63E63511-1C7F-4162-8F92-8F7391B3C8A3} = {025FB189-2FFB-4F43-A64B-6F1B5A0D2065}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -20,10 +20,11 @@ namespace Ombi.Auth
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly TokenProviderOptions _options;
|
private readonly TokenProviderOptions _options;
|
||||||
private readonly JsonSerializerSettings _serializerSettings;
|
private readonly JsonSerializerSettings _serializerSettings;
|
||||||
|
private readonly IUserIdentityManager _identityManager;
|
||||||
|
|
||||||
public TokenProviderMiddleware(
|
public TokenProviderMiddleware(
|
||||||
RequestDelegate next,
|
RequestDelegate next,
|
||||||
IOptions<TokenProviderOptions> options)
|
IOptions<TokenProviderOptions> options, IUserIdentityManager manager)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
|
@ -33,6 +34,7 @@ namespace Ombi.Auth
|
||||||
{
|
{
|
||||||
Formatting = Formatting.Indented
|
Formatting = Formatting.Indented
|
||||||
};
|
};
|
||||||
|
_identityManager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Invoke(HttpContext context)
|
public Task Invoke(HttpContext context)
|
||||||
|
@ -66,7 +68,7 @@ namespace Ombi.Auth
|
||||||
userInfo = JsonConvert.DeserializeObject<UserAuthModel>(body);
|
userInfo = JsonConvert.DeserializeObject<UserAuthModel>(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
var identity = await _options.IdentityResolver(userInfo.Username, userInfo.Password, new UserIdentityManager(new UserRepository(new OmbiContext())));
|
var identity = await _options.IdentityResolver(userInfo.Username, userInfo.Password, _identityManager);
|
||||||
if (identity == null)
|
if (identity == null)
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 400;
|
context.Response.StatusCode = 400;
|
||||||
|
|
26
Ombi/Ombi/Controllers/IdentityController.cs
Normal file
26
Ombi/Ombi/Controllers/IdentityController.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Ombi.Core.IdentityResolver;
|
||||||
|
using Ombi.Core.Models;
|
||||||
|
|
||||||
|
namespace Ombi.Controllers
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
public class IdentityController : BaseV1ApiController
|
||||||
|
{
|
||||||
|
public IdentityController(IUserIdentityManager identity)
|
||||||
|
{
|
||||||
|
IdentityManager = identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IUserIdentityManager IdentityManager { get; }
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<UserDto> GetUser()
|
||||||
|
{
|
||||||
|
return await IdentityManager.GetUser(this.HttpContext.User.Identity.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,16 +8,11 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="wwwroot\app\auth\auth - Copy.module.js.map">
|
|
||||||
<DependentUpon>auth - Copy.module.js</DependentUpon>
|
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="wwwroot\app\auth\auth.guard.ts">
|
<Content Include="wwwroot\app\auth\auth.guard.ts">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="wwwroot\app\auth\auth.module.ts" />
|
<Content Include="wwwroot\app\auth\auth.module.ts" />
|
||||||
<Content Include="wwwroot\app\auth\auth.service.ts" />
|
<Content Include="wwwroot\app\auth\auth.service.ts" />
|
||||||
<Content Include="wwwroot\app\auth\AuthModule.ts" />
|
|
||||||
<Content Include="wwwroot\app\auth\IUserLogin.ts" />
|
<Content Include="wwwroot\app\auth\IUserLogin.ts" />
|
||||||
<Content Include="wwwroot\app\login\login.component.html" />
|
<Content Include="wwwroot\app\login\login.component.html" />
|
||||||
<Content Include="wwwroot\app\login\login.component.ts" />
|
<Content Include="wwwroot\app\login\login.component.ts" />
|
||||||
|
@ -33,8 +28,7 @@
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IdentityServer4" Version="1.4.2" />
|
<PackageReference Include="AutoMapper" Version="6.0.2" />
|
||||||
<PackageReference Include="IdentityServer4.EntityFramework" Version="1.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
||||||
|
@ -52,6 +46,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Mapping\Ombi.Mapping.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
|
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -8,6 +9,7 @@ using Microsoft.Extensions.Options;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Ombi.Auth;
|
using Ombi.Auth;
|
||||||
using Ombi.Core.IdentityResolver;
|
using Ombi.Core.IdentityResolver;
|
||||||
|
using Ombi.Core.Models;
|
||||||
|
|
||||||
namespace Ombi
|
namespace Ombi
|
||||||
{
|
{
|
||||||
|
@ -53,23 +55,20 @@ namespace Ombi
|
||||||
TokenValidationParameters = tokenValidationParameters
|
TokenValidationParameters = tokenValidationParameters
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
|
||||||
{
|
|
||||||
AutomaticAuthenticate = true,
|
|
||||||
AutomaticChallenge = true,
|
|
||||||
AuthenticationScheme = "Cookie",
|
|
||||||
CookieName = Configuration.GetSection("TokenAuthentication:CookieName").Value,
|
|
||||||
TicketDataFormat = new CustomJwtDataFormat(
|
|
||||||
SecurityAlgorithms.HmacSha256,
|
|
||||||
tokenValidationParameters)
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseMiddleware<TokenProviderMiddleware>(Options.Create(tokenProviderOptions));
|
app.UseMiddleware<TokenProviderMiddleware>(Options.Create(tokenProviderOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<ClaimsIdentity> GetIdentity(string username, string password, IUserIdentityManager userIdentityManager)
|
private async Task<ClaimsIdentity> GetIdentity(string username, string password, IUserIdentityManager userIdentityManager)
|
||||||
{
|
{
|
||||||
|
//await userIdentityManager.CreateUser(new UserDto
|
||||||
|
//{
|
||||||
|
// Username = "a",
|
||||||
|
// Password = "a",
|
||||||
|
// Claims = new List<Claim>() { new Claim(ClaimTypes.Role, "Admin")},
|
||||||
|
// UserType = UserType.LocalUser,
|
||||||
|
//});
|
||||||
|
|
||||||
var validLogin = await userIdentityManager.CredentialsValid(username, password);
|
var validLogin = await userIdentityManager.CredentialsValid(username, password);
|
||||||
if (!validLogin)
|
if (!validLogin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,24 +1,12 @@
|
||||||
using System;
|
using AutoMapper;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using IdentityServer4.EntityFramework.DbContexts;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Diagnostics;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ombi.Auth;
|
|
||||||
using Ombi.DependencyInjection;
|
using Ombi.DependencyInjection;
|
||||||
using Ombi.Models;
|
using Ombi.Mapping;
|
||||||
using Ombi.Store.Context;
|
|
||||||
|
|
||||||
namespace Ombi
|
namespace Ombi
|
||||||
{
|
{
|
||||||
|
@ -42,6 +30,8 @@ namespace Ombi
|
||||||
{
|
{
|
||||||
// Add framework services.
|
// Add framework services.
|
||||||
services.AddMvc();
|
services.AddMvc();
|
||||||
|
services.AddOmbiMappingProfile();
|
||||||
|
services.AddAutoMapper();
|
||||||
services.RegisterDependencies(); // Ioc and EF
|
services.RegisterDependencies(); // Ioc and EF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>@ViewData["Title"] - Ombi</title>
|
<title>Ombi</title>
|
||||||
<base href="@Url.Content("~/")" />
|
<base href="@Url.Content("~/")" />
|
||||||
<script src="@Url.Content("~/lib/pace.js")?v=@ViewBag.AssemblyVersion"></script>
|
<script src="@Url.Content("~/lib/pace.js")?v=@ViewBag.AssemblyVersion"></script>
|
||||||
<link href="@Url.Content("~/css/lib/pace-theme-minimal.css")" rel="stylesheet" />
|
<link href="@Url.Content("~/css/lib/pace-theme-minimal.css")" rel="stylesheet" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"SecretKey": "secretkey_secretkey123!",
|
"SecretKey": "secretkey_secretkey123!",
|
||||||
"Issuer": "DemoIssuer",
|
"Issuer": "DemoIssuer",
|
||||||
"Audience": "DemoAudience",
|
"Audience": "DemoAudience",
|
||||||
"TokenPath": "/api/token/",
|
"TokenPath": "/api/v1/token/",
|
||||||
"CookieName": "access_token"
|
"CookieName": "access_token"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { Http } from '@angular/http';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService extends ServiceHelpers {
|
export class AuthService extends ServiceHelpers {
|
||||||
constructor(http: Http) {
|
constructor(http: Http) {
|
||||||
super(http, '/api/token');
|
super(http, '/api/v1/token');
|
||||||
}
|
}
|
||||||
|
|
||||||
login(login:IUserLogin) : Observable<any> {
|
login(login:IUserLogin) : Observable<any> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue