mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 16:22:55 -07:00
Removed IdentityServer, it was overkill #865
This commit is contained in:
parent
7645aff996
commit
046211e017
17 changed files with 226 additions and 346 deletions
|
@ -7,14 +7,12 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.IdentityResolver;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using IdentityModel;
|
||||
using IdentityServer4.Extensions;
|
||||
using IdentityServer4.Models;
|
||||
using IdentityServer4.Services;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Core.IdentityResolver
|
||||
{
|
||||
public class OmbiProfileService : IProfileService
|
||||
{
|
||||
public OmbiProfileService(UserManager<OmbiUser> um)
|
||||
{
|
||||
UserManager = um;
|
||||
}
|
||||
|
||||
private UserManager<OmbiUser> UserManager { get; }
|
||||
|
||||
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
|
||||
{
|
||||
|
||||
if (context.RequestedClaimTypes.Any())
|
||||
{
|
||||
var user = await UserManager.Users.FirstOrDefaultAsync(x => x.UserName == context.Subject.GetSubjectId());
|
||||
if (user != null)
|
||||
{
|
||||
var roles = await UserManager.GetRolesAsync(user);
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(JwtClaimTypes.Name, user.UserName)
|
||||
};
|
||||
|
||||
foreach (var role in roles)
|
||||
{
|
||||
claims.Add(new Claim(JwtClaimTypes.Role, role));
|
||||
}
|
||||
context.AddFilteredClaims(claims);
|
||||
context.IssuedClaims.AddRange(claims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task IsActiveAsync(IsActiveContext context)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using IdentityServer4.Models;
|
||||
using IdentityServer4.Validation;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Emby;
|
||||
using Ombi.Api.Emby.Models;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Api.Plex.Models;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Core.IdentityResolver
|
||||
{
|
||||
public class OmbiOwnerPasswordValidator : IResourceOwnerPasswordValidator
|
||||
{
|
||||
public OmbiOwnerPasswordValidator(UserManager<OmbiUser> um, IPlexApi plexApi, IEmbyApi embyApi,
|
||||
ISettingsService<PlexSettings> settings, ISettingsService<OmbiSettings> ombiSettings,
|
||||
ISettingsService<EmbySettings> embySettings, IAuditRepository log)
|
||||
{
|
||||
UserManager = um;
|
||||
PlexApi = plexApi;
|
||||
PlexSettings = settings;
|
||||
OmbiSettings = ombiSettings;
|
||||
EmbyApi = embyApi;
|
||||
EmbySettings = embySettings;
|
||||
Audit = log;
|
||||
}
|
||||
|
||||
private UserManager<OmbiUser> UserManager { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private IEmbyApi EmbyApi{ get; }
|
||||
private ISettingsService<PlexSettings> PlexSettings { get; }
|
||||
private ISettingsService<EmbySettings> EmbySettings { get; }
|
||||
private ISettingsService<OmbiSettings> OmbiSettings { get; }
|
||||
private IAuditRepository Audit { get; }
|
||||
|
||||
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
|
||||
{
|
||||
await Audit.Record(AuditType.None, AuditArea.Authentication, $"User {context.UserName} attempted to login", context.UserName);
|
||||
var users = UserManager.Users;
|
||||
if (await LocalUser(context, users))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ombi = await OmbiSettings.GetSettingsAsync();
|
||||
if (ombi.AllowExternalUsersToAuthenticate)
|
||||
{
|
||||
if (await PlexUser(context, users))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (await EmbyUser(context, users))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await Audit.Record(AuditType.Fail, AuditArea.Authentication, $"User {context.UserName} failed to login", context.UserName);
|
||||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
|
||||
}
|
||||
|
||||
private async Task<bool> PlexUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
|
||||
{
|
||||
var signInResult = await PlexApi.SignIn(new UserRequest {login = context.UserName, password = context.Password});
|
||||
if (signInResult?.user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do we have a local user?
|
||||
return await GetUserDetails(context, users, UserType.PlexUser);
|
||||
}
|
||||
|
||||
private async Task<bool> EmbyUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
|
||||
{
|
||||
var embySettings = await EmbySettings.GetSettingsAsync();
|
||||
var signInResult = await EmbyApi.LogIn(context.UserName, context.Password, embySettings.ApiKey,
|
||||
embySettings.FullUri);
|
||||
|
||||
if (string.IsNullOrEmpty(signInResult?.Name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return await GetUserDetails(context, users, UserType.EmbyUser);
|
||||
}
|
||||
|
||||
private async Task<bool> GetUserDetails(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users, UserType userType)
|
||||
{
|
||||
var user = await users.FirstOrDefaultAsync(x => x.UserName == context.UserName && x.UserType == userType);
|
||||
if (user != null)
|
||||
{
|
||||
var roles = await UserManager.GetRolesAsync(user);
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, user.UserName)
|
||||
};
|
||||
|
||||
foreach (var role in roles)
|
||||
{
|
||||
claims.Add(new Claim(ClaimTypes.Role, role));
|
||||
}
|
||||
context.Result = new GrantValidationResult(user.UserName, "password", claims);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the user?
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> LocalUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
|
||||
{
|
||||
var user = await users.FirstOrDefaultAsync(x => x.UserName == context.UserName && x.UserType == UserType.LocalUser);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var passwordValid = await UserManager.CheckPasswordAsync(user, context.Password);
|
||||
if (!passwordValid)
|
||||
{
|
||||
await Audit.Record(AuditType.Fail, AuditArea.Authentication, $"User {context.UserName} failed to login", context.UserName);
|
||||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
var roles = await UserManager.GetRolesAsync(user);
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, user.UserName)
|
||||
};
|
||||
|
||||
foreach (var role in roles)
|
||||
{
|
||||
claims.Add(new Claim(ClaimTypes.Role, role));
|
||||
}
|
||||
context.Result = new GrantValidationResult(user.UserName, "password", claims);
|
||||
|
||||
await Audit.Record(AuditType.Success, AuditArea.Authentication, $"User {context.UserName} has logged in", context.UserName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
<PackageReference Include="AutoMapper" Version="6.1.0" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
|
||||
<PackageReference Include="Hangfire" Version="1.6.14" />
|
||||
<PackageReference Include="IdentityServer4" Version="1.5.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.2" />
|
||||
|
|
|
@ -14,7 +14,6 @@ using Ombi.Api.TvMaze;
|
|||
using Ombi.Core;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.IdentityResolver;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Notifications;
|
||||
using Ombi.Core.Rule;
|
||||
|
|
|
@ -7,28 +7,21 @@ import { IUserLogin, ILocalUser } from './IUserLogin';
|
|||
|
||||
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
|
||||
|
||||
import { Http, Headers, URLSearchParams } from '@angular/http';
|
||||
import { Http, Headers } from '@angular/http';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService extends ServiceHelpers {
|
||||
constructor(http: Http) {
|
||||
super(http, '/connect/token');
|
||||
super(http, '/api/v1/token');
|
||||
}
|
||||
|
||||
jwtHelper: JwtHelper = new JwtHelper();
|
||||
|
||||
login(login: IUserLogin): Observable<any> {
|
||||
this.headers = new Headers();
|
||||
this.headers.append('Content-Type', 'application/x-www-form-urlencoded');
|
||||
let data = new URLSearchParams();
|
||||
data.append('client_id', 'frontend');
|
||||
data.append('scope', 'api');
|
||||
data.append('client_secret', 'secret');
|
||||
data.append('grant_type', 'password');
|
||||
data.append('username', login.username);
|
||||
data.append('password', login.password);
|
||||
this.headers.append('Content-Type', 'application/json');
|
||||
|
||||
return this.http.post(`${this.url}/`, data.toString(), { headers: this.headers })
|
||||
return this.http.post(`${this.url}/`, JSON.stringify(login), { headers: this.headers })
|
||||
.map(this.extractData);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
<img class="landing-header" src="/images/logo.png" width="300" />
|
||||
<div class="landing-block shadow">
|
||||
<div class="media">
|
||||
<div id="contentBody" class="media-body">
|
||||
<h4 class="media-heading landing-title">Create the Admin account</h4>
|
||||
<small>This account will be used to configure your settings and also manage all of the requests. Note: this should not be the same as your Plex/Emby account (you can change this later in the User Management Settings)</small>
|
||||
<div class="form-group">
|
||||
|
@ -18,3 +22,6 @@
|
|||
<button (click)="createUser()" type="submit" class="btn btn-success-outline">Finish</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
<img class="landing-header" src="/images/logo.png" width="300" />
|
||||
<div class="landing-block shadow">
|
||||
<div class="media">
|
||||
<div id="contentBody" class="media-body">
|
||||
<h4 class="media-heading landing-title">Emby Authentication</h4>
|
||||
<div *ngIf="embySettings">
|
||||
<div class="form-group">
|
||||
|
@ -30,3 +34,6 @@
|
|||
<a (click)="save()" id="embyApiKeySave" class="btn btn-primary-outline">Next <div id="spinner"></div></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,8 @@
|
|||
<div>
|
||||
|
||||
<img class="landing-header" src="/images/logo.png" width="300" />
|
||||
<div class="landing-block shadow">
|
||||
<div class="media">
|
||||
<div id="contentBody" class="media-body">
|
||||
<h4 class="media-heading landing-title wizard-heading" id="statusTitle">Please choose your media server</h4>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
|
@ -18,4 +22,8 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import { Router } from '@angular/router';
|
|||
|
||||
|
||||
@Component({
|
||||
|
||||
templateUrl: './mediaserver.component.html',
|
||||
})
|
||||
export class MediaServerComponent {
|
||||
|
@ -19,8 +18,7 @@ export class MediaServerComponent {
|
|||
this.router.navigate(['Wizard/Emby']);
|
||||
}
|
||||
|
||||
skip()
|
||||
{
|
||||
skip() {
|
||||
this.router.navigate(['Wizard/CreateAdmin']);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
<h4 class="media-heading landing-title">Plex Authentication</h4>
|
||||
|
||||
<img class="landing-header" src="/images/logo.png" width="300" />
|
||||
<div class="landing-block shadow">
|
||||
<div class="media">
|
||||
<div id="contentBody" class="media-body">
|
||||
<h4 class="media-heading landing-title">Plex Authentication</h4>
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label">Username and Password</label>
|
||||
<div>
|
||||
|
@ -15,3 +20,6 @@
|
|||
<button (click)="requestAuthToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
106
src/Ombi/Controllers/TokenController.cs
Normal file
106
src/Ombi/Controllers/TokenController.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Ombi.Models;
|
||||
using Ombi.Models.Identity;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
[ApiV1]
|
||||
public class TokenController
|
||||
{
|
||||
public TokenController(UserManager<OmbiUser> um, IOptions<TokenAuthentication> ta,
|
||||
IApplicationConfigRepository config)
|
||||
{
|
||||
UserManager = um;
|
||||
TokenAuthenticationOptions = ta.Value;
|
||||
Config = config;
|
||||
}
|
||||
|
||||
private TokenAuthentication TokenAuthenticationOptions { get; }
|
||||
private IApplicationConfigRepository Config { get; }
|
||||
private UserManager<OmbiUser> UserManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the token.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetToken([FromBody] UserAuthModel model)
|
||||
{
|
||||
|
||||
var user = await UserManager.FindByNameAsync(model.Username);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Verify Password
|
||||
if ((await UserManager.CheckPasswordAsync(user, model.Password)))
|
||||
{
|
||||
// Get the url
|
||||
var url = Config.Get(ConfigurationTypes.Url);
|
||||
var port = Config.Get(ConfigurationTypes.Port);
|
||||
|
||||
#if !DEBUG
|
||||
var audience = $"{url}:{port}";
|
||||
#else
|
||||
|
||||
var audience = $"http://localhost:52038/";
|
||||
#endif
|
||||
var roles = await UserManager.GetRolesAsync(user);
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
|
||||
new Claim("name", user.UserName),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
||||
};
|
||||
claims.AddRange(roles.Select(role => new Claim("role", role)));
|
||||
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenAuthenticationOptions.SecretKey));
|
||||
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
var token = new JwtSecurityToken(
|
||||
claims: claims,
|
||||
expires: DateTime.UtcNow.AddHours(5),
|
||||
signingCredentials: creds,
|
||||
audience: "Ombi", issuer:"Ombi"
|
||||
);
|
||||
|
||||
return new JsonResult(new
|
||||
{
|
||||
access_token = new JwtSecurityTokenHandler().WriteToken(token),
|
||||
expiration = token.ValidTo
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the token.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
[HttpPost("refresh")]
|
||||
public async Task<IActionResult> RefreshToken([FromBody] UserAuthModel model)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using IdentityModel;
|
||||
using IdentityServer4.Models;
|
||||
|
||||
namespace Ombi
|
||||
{
|
||||
public class IdentityConfig
|
||||
{
|
||||
// scopes define the resources in your system
|
||||
public static IEnumerable<IdentityResource> GetIdentityResources()
|
||||
{
|
||||
return new List<IdentityResource>
|
||||
{
|
||||
new IdentityResources.OpenId(),
|
||||
new IdentityResources.Profile(),
|
||||
new IdentityResource {
|
||||
Name = "role",
|
||||
UserClaims = new List<string> {"role"}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static IEnumerable<ApiResource> GetApiResources()
|
||||
{
|
||||
return new List<ApiResource>
|
||||
{
|
||||
new ApiResource("api", "API")
|
||||
{
|
||||
UserClaims = {JwtClaimTypes.Name, JwtClaimTypes.Role, JwtClaimTypes.Email, JwtClaimTypes.Id},
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// clients want to access resources (aka scopes)
|
||||
public static IEnumerable<Client> GetClients()
|
||||
{
|
||||
// client credentials client
|
||||
return new List<Client>
|
||||
{
|
||||
new Client
|
||||
{
|
||||
ClientId = "frontend",
|
||||
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
||||
|
||||
ClientSecrets =
|
||||
{
|
||||
new Secret("secret".Sha256()) // TODO read up on what this actually is
|
||||
},
|
||||
AllowedScopes =
|
||||
{
|
||||
"api",
|
||||
},
|
||||
AccessTokenType = AccessTokenType.Jwt
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
7
src/Ombi/Models/Identity/TokenAuthentication.cs
Normal file
7
src/Ombi/Models/Identity/TokenAuthentication.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Ombi.Models.Identity
|
||||
{
|
||||
public class TokenAuthentication
|
||||
{
|
||||
public string SecretKey { get; set; }
|
||||
}
|
||||
}
|
|
@ -43,9 +43,6 @@
|
|||
<PackageReference Include="Hangfire.MemoryStorage.Core" Version="1.4.0" />
|
||||
<PackageReference Include="Hangfire.RecurringJobExtensions" Version="1.1.6" />
|
||||
<PackageReference Include="Hangfire.SQLite.Core" Version="1.0.2" />
|
||||
<PackageReference Include="IdentityServer4" Version="1.5.2" />
|
||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.1" />
|
||||
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="1.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using AutoMapper;
|
||||
using AutoMapper.EquivalencyExpression;
|
||||
using Hangfire;
|
||||
using Hangfire.MemoryStorage;
|
||||
using Hangfire.SQLite;
|
||||
using IdentityServer4.Services;
|
||||
using IdentityServer4.Validation;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||
|
@ -25,10 +22,10 @@ using Microsoft.Extensions.Options;
|
|||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.IdentityResolver;
|
||||
using Ombi.DependencyInjection;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Mapping;
|
||||
using Ombi.Models.Identity;
|
||||
using Ombi.Schedule;
|
||||
using Ombi.Store.Context;
|
||||
using Ombi.Store.Entities;
|
||||
|
@ -83,15 +80,16 @@ namespace Ombi
|
|||
.AddEntityFrameworkStores<OmbiContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.AddIdentityServer()
|
||||
.AddTemporarySigningCredential()
|
||||
.AddInMemoryPersistedGrants()
|
||||
.AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
|
||||
.AddInMemoryApiResources(IdentityConfig.GetApiResources())
|
||||
.AddInMemoryClients(IdentityConfig.GetClients())
|
||||
.AddAspNetIdentity<OmbiUser>()
|
||||
.Services.AddTransient<IResourceOwnerPasswordValidator, OmbiOwnerPasswordValidator>()
|
||||
.AddTransient<IProfileService, OmbiProfileService>();
|
||||
|
||||
//services.AddIdentityServer()
|
||||
// .AddTemporarySigningCredential()
|
||||
// .AddInMemoryPersistedGrants()
|
||||
// .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
|
||||
// .AddInMemoryApiResources(IdentityConfig.GetApiResources())
|
||||
// .AddInMemoryClients(IdentityConfig.GetClients())
|
||||
// .AddAspNetIdentity<OmbiUser>()
|
||||
// .Services.AddTransient<IResourceOwnerPasswordValidator, OmbiOwnerPasswordValidator>()
|
||||
// .AddTransient<IProfileService, OmbiProfileService>();
|
||||
|
||||
services.Configure<IdentityOptions>(options =>
|
||||
{
|
||||
|
@ -151,10 +149,9 @@ namespace Ombi
|
|||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddScoped<IPrincipal>(sp => sp.GetService<IHttpContextAccessor>().HttpContext.User);
|
||||
|
||||
|
||||
//services.Configure<TokenAuthenticationOptions>(Configuration.GetSection("TokenAuthentication"));
|
||||
services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
|
||||
services.Configure<UserSettings>(Configuration.GetSection("UserSettings"));
|
||||
services.Configure<TokenAuthentication>(Configuration.GetSection("TokenAuthentication"));
|
||||
services.Configure<LandingPageBackground>(Configuration.GetSection("LandingPageBackground"));
|
||||
|
||||
services.AddHangfire(x =>
|
||||
|
@ -179,8 +176,8 @@ namespace Ombi
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache)
|
||||
{
|
||||
var options = (IOptions<UserSettings>) app.ApplicationServices.GetService(
|
||||
typeof(IOptions<UserSettings>));
|
||||
var tokenOptions = (IOptions<TokenAuthentication>)app.ApplicationServices.GetService(
|
||||
typeof(IOptions<TokenAuthentication>));
|
||||
|
||||
var ctx = (IOmbiContext)app.ApplicationServices.GetService(typeof(IOmbiContext));
|
||||
|
||||
|
@ -190,26 +187,54 @@ namespace Ombi
|
|||
|
||||
Console.WriteLine($"Using Url {url.Value}:{port.Value} for Identity Server");
|
||||
app.UseIdentity();
|
||||
app.UseIdentityServer();
|
||||
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
||||
{
|
||||
|
||||
#if !DEBUG
|
||||
Authority = $"{url.Value}:{port.Value}",
|
||||
var audience = $"{url.Value}:{port.Value}";
|
||||
#else
|
||||
Authority = $"http://localhost:52038/",
|
||||
|
||||
var audience = $"http://localhost:52038/";
|
||||
#endif
|
||||
ApiName = "api",
|
||||
ApiSecret = "secret",
|
||||
|
||||
EnableCaching = true,
|
||||
CacheDuration = TimeSpan.FromMinutes(10), // that's the default
|
||||
RequireHttpsMetadata = options.Value.UseHttps, // FOR DEV set to false
|
||||
var tokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.Value.SecretKey)),
|
||||
|
||||
RequireExpirationTime = true,
|
||||
ValidateLifetime = true,
|
||||
ValidAudience = "Ombi",
|
||||
ValidIssuer = "Ombi",
|
||||
ClockSkew = TimeSpan.Zero
|
||||
};
|
||||
|
||||
app.UseJwtBearerAuthentication(new JwtBearerOptions()
|
||||
{
|
||||
Audience = "Ombi",
|
||||
AutomaticAuthenticate = true,
|
||||
AutomaticChallenge = true,
|
||||
|
||||
|
||||
TokenValidationParameters = tokenValidationParameters
|
||||
});
|
||||
|
||||
// app.UseIdentityServer();
|
||||
// app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
||||
// {
|
||||
//#if !DEBUG
|
||||
// Authority = $"{url.Value}:{port.Value}",
|
||||
//#else
|
||||
// Authority = $"http://localhost:52038/",
|
||||
//#endif
|
||||
// ApiName = "api",
|
||||
// ApiSecret = "secret",
|
||||
|
||||
// EnableCaching = true,
|
||||
// CacheDuration = TimeSpan.FromMinutes(10), // that's the default
|
||||
// RequireHttpsMetadata = options.Value.UseHttps, // FOR DEV set to false
|
||||
// AutomaticAuthenticate = true,
|
||||
// AutomaticChallenge = true,
|
||||
|
||||
|
||||
// });
|
||||
|
||||
loggerFactory.AddSerilog();
|
||||
|
||||
if (env.IsDevelopment())
|
||||
|
|
|
@ -16,11 +16,7 @@
|
|||
"UseHttps": false
|
||||
},
|
||||
"TokenAuthentication": {
|
||||
"SecretKey": "secretkey_secretkey123!",
|
||||
"Issuer": "OmbiIssuer",
|
||||
"Audience": "OmbiAudience",
|
||||
"TokenPath": "/api/v1/token/",
|
||||
"CookieName": "access_token"
|
||||
"SecretKey": "secretkey_secretkey123!"
|
||||
},
|
||||
"LandingPageBackground": {
|
||||
"Movies": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue