Add Stylecop
This commit is contained in:
Родитель
d8f92cccee
Коммит
c5af0cd93d
|
@ -153,7 +153,6 @@ AppPackages/
|
|||
# Others
|
||||
*.[Cc]ache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
|
|
|
@ -5,11 +5,11 @@ env:
|
|||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
mono: none
|
||||
dotnet: 2.0.0
|
||||
dotnet: 2.0.3
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
osx_image: xcode8.2
|
||||
osx_image: xcode8.3
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
<PropertyGroup>
|
||||
<SteeltoeVersion>$(STEELTOE_VERSION)</SteeltoeVersion>
|
||||
<SteeltoeVersionSuffix>$(STEELTOE_DASH_VERSION_SUFFIX)</SteeltoeVersionSuffix>
|
||||
<SteeltoeConnectorVersion>2.0.0-dev-00192</SteeltoeConnectorVersion>
|
||||
<SteeltoeCommonVersion>2.0.0-dev-00022</SteeltoeCommonVersion>
|
||||
<SteeltoeConnectorVersion>2.0.0-dev-00198</SteeltoeConnectorVersion>
|
||||
<SteeltoeCommonVersion>2.0.0-dev-00040</SteeltoeCommonVersion>
|
||||
<AspNetCoreVersion>2.0.0</AspNetCoreVersion>
|
||||
<AspNetCoreDataProtectionRedisVersion>0.3.0</AspNetCoreDataProtectionRedisVersion>
|
||||
<AspNetCoreTestVersion>2.0.0</AspNetCoreTestVersion>
|
||||
<AspNetCoreMvcTestVersion>2.0.0</AspNetCoreMvcTestVersion>
|
||||
<AspNetCoreDepTestVersion>2.0.0</AspNetCoreDepTestVersion>
|
||||
<CoreFxVersion>4.4.0</CoreFxVersion>
|
||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||
<TestSdkVersion>15.3.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.0-beta4-build3742</XunitVersion>
|
||||
<XunitStudioVersion>2.3.0-beta4-build3742</XunitStudioVersion>
|
||||
<StyleCopVersion>1.0.2</StyleCopVersion>
|
||||
<JsonNetVersion>10.0.3</JsonNetVersion>
|
||||
<TestSdkVersion>15.5.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.1</XunitVersion>
|
||||
<XunitStudioVersion>2.3.1</XunitStudioVersion>
|
||||
<HttpClientVersion>4.3.3</HttpClientVersion>
|
||||
<OwinOAuthVerions>3.1.0</OwinOAuthVerions>
|
||||
<JwtTokensVerions>5.1.4</JwtTokensVerions>
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
<PropertyGroup>
|
||||
<SteeltoeVersion>$(STEELTOE_VERSION)</SteeltoeVersion>
|
||||
<SteeltoeVersionSuffix>$(STEELTOE_DASH_VERSION_SUFFIX)</SteeltoeVersionSuffix>
|
||||
<SteeltoeConnectorVersion>2.0.0-master-00173</SteeltoeConnectorVersion>
|
||||
<SteeltoeConnectorVersion>2.0.0-master-00199</SteeltoeConnectorVersion>
|
||||
<SteeltoeCommonVersion>2.0.0-master-00041</SteeltoeCommonVersion>
|
||||
<AspNetCoreVersion>2.0.0</AspNetCoreVersion>
|
||||
<AspNetCoreDataProtectionRedisVersion>0.3.0</AspNetCoreDataProtectionRedisVersion>
|
||||
<AspNetCoreTestVersion>2.0.0</AspNetCoreTestVersion>
|
||||
<AspNetCoreMvcTestVersion>2.0.0</AspNetCoreMvcTestVersion>
|
||||
<AspNetCoreDepTestVersion>2.0.0</AspNetCoreDepTestVersion>
|
||||
<CoreFxVersion>4.4.0</CoreFxVersion>
|
||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||
<TestSdkVersion>15.3.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.0-beta4-build3742</XunitVersion>
|
||||
<XunitStudioVersion>2.3.0-beta4-build3742</XunitStudioVersion>
|
||||
<StyleCopVersion>1.0.2</StyleCopVersion>
|
||||
<JsonNetVersion>10.0.3</JsonNetVersion>
|
||||
<TestSdkVersion>15.5.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.1</XunitVersion>
|
||||
<XunitStudioVersion>2.3.1</XunitStudioVersion>
|
||||
<HttpClientVersion>4.3.3</HttpClientVersion>
|
||||
<OwinOAuthVerions>3.1.0</OwinOAuthVerions>
|
||||
<JwtTokensVerions>5.1.4</JwtTokensVerions>
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
<AspNetCoreMvcTestVersion>2.0.0</AspNetCoreMvcTestVersion>
|
||||
<AspNetCoreDepTestVersion>2.0.0</AspNetCoreDepTestVersion>
|
||||
<CoreFxVersion>4.4.0</CoreFxVersion>
|
||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||
<TestSdkVersion>15.3.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.0-beta4-build3742</XunitVersion>
|
||||
<XunitStudioVersion>2.3.0-beta4-build3742</XunitStudioVersion>
|
||||
<StyleCopVersion>1.0.2</StyleCopVersion>
|
||||
<JsonNetVersion>10.0.3</JsonNetVersion>
|
||||
<TestSdkVersion>15.5.0</TestSdkVersion>
|
||||
<XunitVersion>2.3.1</XunitVersion>
|
||||
<XunitStudioVersion>2.3.1</XunitStudioVersion>
|
||||
<HttpClientVersion>4.3.3</HttpClientVersion>
|
||||
<OwinOAuthVerions>3.1.0</OwinOAuthVerions>
|
||||
<JwtTokensVerions>5.1.4</JwtTokensVerions>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,25 +11,22 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
public static class CloudFoundryClaimActionExtensions
|
||||
{
|
||||
public static void MapScopes(this ClaimActionCollection collection, string claimType = "scope")
|
||||
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
|
||||
|
||||
collection.Add(new CloudFoundryScopeClaimAction(claimType, ClaimValueTypes.String));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,12 +11,11 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Steeltoe.CloudFoundry.Connector;
|
||||
using Steeltoe.CloudFoundry.Connector.Services;
|
||||
using System;
|
||||
|
@ -41,7 +39,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
SsoServiceInfo info = config.GetSingletonServiceInfo<SsoServiceInfo>();
|
||||
CloudFoundryOAuthConfigurer.Configure(info, options);
|
||||
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
@ -77,7 +74,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
SsoServiceInfo info = config.GetSingletonServiceInfo<SsoServiceInfo>();
|
||||
CloudFoundryJwtBearerConfigurer.Configure(info, options, cloudFoundryOptions);
|
||||
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,17 +11,15 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Steeltoe.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Steeltoe.Common;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
|
||||
public static class CloudFoundryHelper
|
||||
{
|
||||
public static DateTime GetIssueTime(JObject payload)
|
||||
|
@ -31,6 +28,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
throw new ArgumentNullException(nameof(payload));
|
||||
}
|
||||
|
||||
var time = payload.Value<long>("iat");
|
||||
return ToAbsoluteUTC(time);
|
||||
}
|
||||
|
@ -41,17 +39,21 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
throw new ArgumentNullException(nameof(payload));
|
||||
}
|
||||
|
||||
var time = payload.Value<long>("exp");
|
||||
return ToAbsoluteUTC(time);
|
||||
}
|
||||
|
||||
private static DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
private static DateTime ToAbsoluteUTC(long secondsPastEpoch)
|
||||
{
|
||||
return baseTime.AddSeconds(secondsPastEpoch);
|
||||
}
|
||||
|
||||
#pragma warning disable SA1202 // Elements must be ordered by access
|
||||
public static List<string> GetScopes(JObject user)
|
||||
#pragma warning restore SA1202 // Elements must be ordered by access
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
|
@ -71,6 +73,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
result.Add(asValue.Value<string>());
|
||||
return result;
|
||||
}
|
||||
|
||||
var asArray = scopes as JArray;
|
||||
if (asArray != null)
|
||||
{
|
||||
|
@ -79,12 +82,12 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
result.Add(s);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static HttpMessageHandler GetBackChannelHandler(bool validateCertificates)
|
||||
{
|
||||
|
||||
if (Platform.IsFullFramework)
|
||||
{
|
||||
return null;
|
||||
|
@ -93,14 +96,15 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
if (!validateCertificates)
|
||||
{
|
||||
var handler = new HttpClientHandler();
|
||||
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
@ -25,7 +23,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
internal static void Configure(SsoServiceInfo si, JwtBearerOptions jwtOptions, CloudFoundryJwtBearerOptions options)
|
||||
{
|
||||
|
||||
if (jwtOptions == null || options == null)
|
||||
{
|
||||
return;
|
||||
|
@ -33,21 +30,21 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
if (si != null)
|
||||
{
|
||||
options.JwtKeyUrl = si.AuthDomain + CloudFoundryDefaults.JwtTokenKey;
|
||||
options.JwtKeyUrl = si.AuthDomain + CloudFoundryDefaults.JwtTokenKey;
|
||||
}
|
||||
|
||||
jwtOptions.ClaimsIssuer = options.ClaimsIssuer;
|
||||
jwtOptions.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates);
|
||||
jwtOptions.TokenValidationParameters = GetTokenValidationParameters(jwtOptions.TokenValidationParameters, options.JwtKeyUrl, jwtOptions.BackchannelHttpHandler, options.ValidateCertificates);
|
||||
jwtOptions.SaveToken = options.SaveToken;
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal static TokenValidationParameters GetTokenValidationParameters(TokenValidationParameters parameters, string keyUrl, HttpMessageHandler handler, bool validateCertificates)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
parameters = new TokenValidationParameters();
|
||||
}
|
||||
|
||||
parameters.ValidateAudience = false;
|
||||
parameters.ValidateIssuer = true;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,26 +11,25 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
public class CloudFoundryJwtBearerOptions : JwtBearerOptions
|
||||
{
|
||||
public string JwtKeyUrl { get; set; }
|
||||
|
||||
public bool Validate_Certificates { get; set; } = true;
|
||||
|
||||
public bool ValidateCertificates => Validate_Certificates;
|
||||
|
||||
public CloudFoundryJwtBearerOptions()
|
||||
{
|
||||
string authURL = "http://" + CloudFoundryDefaults.OAuthServiceUrl;
|
||||
ClaimsIssuer = CloudFoundryDefaults.AuthenticationScheme;
|
||||
ClaimsIssuer = CloudFoundryDefaults.AuthenticationScheme;
|
||||
JwtKeyUrl = authURL + CloudFoundryDefaults.JwtTokenKey;
|
||||
SaveToken = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,12 +11,8 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Steeltoe.CloudFoundry.Connector.Services;
|
||||
using Steeltoe.Common;
|
||||
using System.Net.Http;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
|
@ -29,6 +24,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (si != null)
|
||||
{
|
||||
options.ClientId = si.ClientId;
|
||||
|
@ -37,15 +33,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
options.TokenEndpoint = si.AuthDomain + CloudFoundryDefaults.AccessTokenUri;
|
||||
options.UserInformationEndpoint = si.AuthDomain + CloudFoundryDefaults.UserInfoUri;
|
||||
options.TokenInfoUrl = si.AuthDomain + CloudFoundryDefaults.CheckTokenUri;
|
||||
|
||||
}
|
||||
|
||||
options.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -12,51 +11,120 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Steeltoe.Common.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.Encodings.Web;
|
||||
using Steeltoe.Common.Http;
|
||||
using System.Net.Security;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Security;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
public class CloudFoundryOAuthHandler : OAuthHandler<CloudFoundryOAuthOptions>
|
||||
{
|
||||
ILogger<CloudFoundryOAuthHandler> _logger;
|
||||
private ILogger<CloudFoundryOAuthHandler> _logger;
|
||||
|
||||
public CloudFoundryOAuthHandler(
|
||||
IOptionsMonitor<CloudFoundryOAuthOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
_logger = logger?.CreateLogger<CloudFoundryOAuthHandler>();
|
||||
}
|
||||
|
||||
protected internal virtual Dictionary<string, string> GetTokenInfoRequestParameters(OAuthTokenResponse tokens)
|
||||
{
|
||||
_logger?.LogDebug("GetTokenInfoRequestParameters() using token: {token}", tokens.AccessToken);
|
||||
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "token", tokens.AccessToken }
|
||||
};
|
||||
}
|
||||
|
||||
protected internal virtual HttpRequestMessage GetTokenInfoRequestMessage(OAuthTokenResponse tokens)
|
||||
{
|
||||
_logger?.LogDebug("GetTokenInfoRequestMessage({token}) with {clientId}", tokens.AccessToken, Options.ClientId);
|
||||
|
||||
var tokenRequestParameters = GetTokenInfoRequestParameters(tokens);
|
||||
|
||||
var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenInfoUrl);
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", GetEncoded(Options.ClientId, Options.ClientSecret));
|
||||
request.Content = requestContent;
|
||||
return request;
|
||||
}
|
||||
|
||||
protected internal virtual Dictionary<string, string> GetTokenRequestParameters(string code, string redirectUri)
|
||||
{
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "client_id", Options.ClientId },
|
||||
{ "redirect_uri", redirectUri },
|
||||
{ "client_secret", Options.ClientSecret },
|
||||
{ "code", code },
|
||||
{ "grant_type", "authorization_code" },
|
||||
};
|
||||
}
|
||||
|
||||
protected internal virtual HttpRequestMessage GetTokenRequestMessage(string code, string redirectUri)
|
||||
{
|
||||
var tokenRequestParameters = GetTokenRequestParameters(code, redirectUri);
|
||||
|
||||
var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
requestMessage.Content = requestContent;
|
||||
return requestMessage;
|
||||
}
|
||||
|
||||
protected internal string GetEncoded(string user, string password)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
user = string.Empty;
|
||||
}
|
||||
|
||||
if (password == null)
|
||||
{
|
||||
password = string.Empty;
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(Encoding.ASCII.GetBytes(user + ":" + password));
|
||||
}
|
||||
|
||||
protected internal virtual HttpClient GetHttpClient()
|
||||
{
|
||||
return Backchannel;
|
||||
}
|
||||
|
||||
protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri)
|
||||
{
|
||||
|
||||
_logger?.LogDebug("ExchangeCodeAsync({code},{redirectUri})", code, redirectUri);
|
||||
|
||||
HttpRequestMessage requestMessage = GetTokenRequestMessage(code, redirectUri);
|
||||
HttpClient client = GetHttpClient();
|
||||
|
||||
RemoteCertificateValidationCallback prevValidator = null;
|
||||
SecurityProtocolType prevProtocols = (SecurityProtocolType)0;
|
||||
HttpClientHelper.ConfigureCertificateValidatation(Options.ValidateCertificates, out prevProtocols, out prevValidator);
|
||||
HttpClientHelper.ConfigureCertificateValidatation(
|
||||
Options.ValidateCertificates,
|
||||
out SecurityProtocolType prevProtocols,
|
||||
out RemoteCertificateValidationCallback prevValidator);
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
|
@ -67,7 +135,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
HttpClientHelper.RestoreCertificateValidation(Options.ValidateCertificates, prevProtocols, prevValidator);
|
||||
}
|
||||
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -85,7 +153,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
_logger?.LogDebug("CreateTicketAsync()");
|
||||
|
@ -93,9 +160,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
HttpRequestMessage request = GetTokenInfoRequestMessage(tokens);
|
||||
HttpClient client = GetHttpClient();
|
||||
|
||||
RemoteCertificateValidationCallback prevValidator = null;
|
||||
SecurityProtocolType prevProtocols = (SecurityProtocolType)0;
|
||||
HttpClientHelper.ConfigureCertificateValidatation(Options.ValidateCertificates, out prevProtocols, out prevValidator);
|
||||
HttpClientHelper.ConfigureCertificateValidatation(
|
||||
Options.ValidateCertificates,
|
||||
out SecurityProtocolType prevProtocols,
|
||||
out RemoteCertificateValidationCallback prevValidator);
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
|
@ -134,17 +202,18 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
return ticket;
|
||||
}
|
||||
|
||||
|
||||
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
|
||||
{
|
||||
_logger?.LogDebug("BuildChallengeUrl({redirectUri}) with {clientId}", redirectUri, Options.ClientId);
|
||||
|
||||
var scope = FormatScope();
|
||||
|
||||
var queryStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
queryStrings.Add("response_type", "code");
|
||||
queryStrings.Add("client_id", Options.ClientId);
|
||||
queryStrings.Add("redirect_uri", redirectUri);
|
||||
var queryStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "response_type", "code" },
|
||||
{ "client_id", Options.ClientId },
|
||||
{ "redirect_uri", redirectUri }
|
||||
};
|
||||
|
||||
AddQueryString(queryStrings, properties, "scope", scope);
|
||||
|
||||
|
@ -158,73 +227,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
return authorizationEndpoint;
|
||||
}
|
||||
|
||||
internal protected virtual Dictionary<string, string> GetTokenInfoRequestParameters(OAuthTokenResponse tokens)
|
||||
{
|
||||
_logger?.LogDebug("GetTokenInfoRequestParameters() using token: {token}", tokens.AccessToken);
|
||||
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "token", tokens.AccessToken }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
internal protected virtual HttpRequestMessage GetTokenInfoRequestMessage(OAuthTokenResponse tokens)
|
||||
{
|
||||
_logger?.LogDebug("GetTokenInfoRequestMessage({token}) with {clientId}", tokens.AccessToken, Options.ClientId);
|
||||
|
||||
var tokenRequestParameters = GetTokenInfoRequestParameters(tokens);
|
||||
|
||||
var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenInfoUrl);
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", GetEncoded(Options.ClientId, Options.ClientSecret));
|
||||
request.Content = requestContent;
|
||||
return request;
|
||||
}
|
||||
|
||||
internal protected virtual Dictionary<string, string> GetTokenRequestParameters(string code, string redirectUri)
|
||||
{
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "client_id", Options.ClientId },
|
||||
{ "redirect_uri", redirectUri },
|
||||
{ "client_secret", Options.ClientSecret },
|
||||
{ "code", code },
|
||||
{ "grant_type", "authorization_code" },
|
||||
};
|
||||
}
|
||||
|
||||
internal protected virtual HttpRequestMessage GetTokenRequestMessage(string code, string redirectUri)
|
||||
{
|
||||
var tokenRequestParameters = GetTokenRequestParameters(code, redirectUri);
|
||||
|
||||
var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
requestMessage.Content = requestContent;
|
||||
return requestMessage;
|
||||
}
|
||||
|
||||
internal protected string GetEncoded(string user, string password)
|
||||
{
|
||||
if (user == null)
|
||||
user = string.Empty;
|
||||
if (password == null)
|
||||
password = string.Empty;
|
||||
return Convert.ToBase64String(Encoding.ASCII.GetBytes(user + ":" + password));
|
||||
}
|
||||
|
||||
internal protected virtual HttpClient GetHttpClient()
|
||||
{
|
||||
return Backchannel;
|
||||
}
|
||||
|
||||
private static void AddQueryString(IDictionary<string, string> queryStrings, AuthenticationProperties properties, string name, string defaultValue = null)
|
||||
{
|
||||
string value;
|
||||
if (!properties.Items.TryGetValue(name, out value))
|
||||
if (!properties.Items.TryGetValue(name, out string value))
|
||||
{
|
||||
value = defaultValue;
|
||||
}
|
||||
|
@ -240,6 +245,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
queryStrings[name] = value;
|
||||
}
|
||||
|
||||
private static async Task<string> Display(HttpResponseMessage response)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
|
@ -248,6 +254,5 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
output.Append("Body: " + await response.Content.ReadAsStringAsync() + ";");
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -12,23 +11,23 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
|
||||
public class CloudFoundryOAuthOptions : OAuthOptions
|
||||
{
|
||||
|
||||
public string TokenInfoUrl { get; set; }
|
||||
|
||||
public bool Validate_Certificates { get; set; } = true;
|
||||
|
||||
public bool ValidateCertificates => Validate_Certificates;
|
||||
|
||||
public bool UseTokenLifetime { get; set; } = true;
|
||||
|
||||
public CloudFoundryOAuthOptions()
|
||||
|
@ -44,7 +43,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
TokenInfoUrl = authURL + CloudFoundryDefaults.CheckTokenUri;
|
||||
SaveTokens = true;
|
||||
|
||||
|
||||
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "user_id");
|
||||
ClaimActions.MapJsonKey(ClaimTypes.Name, "user_name");
|
||||
ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
|
||||
|
@ -54,6 +52,5 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
@ -22,7 +20,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
public class CloudFoundryScopeClaimAction : ClaimAction
|
||||
{
|
||||
public CloudFoundryScopeClaimAction(string claimType, string valueType)
|
||||
public CloudFoundryScopeClaimAction(string claimType, string valueType)
|
||||
: base(claimType, valueType)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Steeltoe.Common;
|
||||
|
@ -30,7 +28,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
public class CloudFoundryTokenKeyResolver
|
||||
{
|
||||
|
||||
internal static ConcurrentDictionary<string, SecurityKey> Resolved { get; set; } = new ConcurrentDictionary<string, SecurityKey>();
|
||||
|
||||
private string _jwtKeyUrl;
|
||||
|
@ -39,7 +36,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
public CloudFoundryTokenKeyResolver(string jwtKeyUrl, HttpMessageHandler httpHandler, bool validateCertificates)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jwtKeyUrl ))
|
||||
if (string.IsNullOrEmpty(jwtKeyUrl))
|
||||
{
|
||||
throw new ArgumentException(nameof(jwtKeyUrl));
|
||||
}
|
||||
|
@ -51,8 +48,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
public virtual IEnumerable<SecurityKey> ResolveSigningKey(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
|
||||
{
|
||||
SecurityKey resolved = null;
|
||||
if (Resolved.TryGetValue(kid, out resolved))
|
||||
if (Resolved.TryGetValue(kid, out SecurityKey resolved))
|
||||
{
|
||||
return new List<SecurityKey> { resolved };
|
||||
}
|
||||
|
@ -66,34 +62,26 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
Resolved[key.Kid] = key;
|
||||
}
|
||||
}
|
||||
|
||||
if (Resolved.TryGetValue(kid, out resolved))
|
||||
{
|
||||
return new List<SecurityKey> { resolved };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public JsonWebKey FixupKey(JsonWebKey key)
|
||||
{
|
||||
|
||||
if (Platform.IsFullFramework)
|
||||
{
|
||||
|
||||
byte[] existing = Base64UrlEncoder.DecodeBytes(key.N);
|
||||
TrimKey(key, existing);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
private void TrimKey(JsonWebKey key, byte[] existing)
|
||||
{
|
||||
byte[] signRemoved = new byte[existing.Length -1];
|
||||
Buffer.BlockCopy(existing, 1, signRemoved, 0, existing.Length - 1);
|
||||
string withSignRemoved = Base64UrlEncoder.Encode(signRemoved);
|
||||
key.N = withSignRemoved;
|
||||
}
|
||||
|
||||
public virtual async Task<JsonWebKeySet> FetchKeySet()
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, _jwtKeyUrl);
|
||||
|
@ -101,9 +89,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
|
||||
HttpClient client = GetHttpClient();
|
||||
|
||||
RemoteCertificateValidationCallback prevValidator = null;
|
||||
SecurityProtocolType prevProtocols = (SecurityProtocolType)0;
|
||||
HttpClientHelper.ConfigureCertificateValidatation(_validateCertificates, out prevProtocols, out prevValidator);
|
||||
HttpClientHelper.ConfigureCertificateValidatation(
|
||||
_validateCertificates,
|
||||
out SecurityProtocolType prevProtocols,
|
||||
out RemoteCertificateValidationCallback prevValidator);
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
|
@ -120,6 +109,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
var result = await response.Content.ReadAsStringAsync();
|
||||
return GetJsonWebKeySet(result);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -134,7 +124,16 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
return new HttpClient(_httpHandler);
|
||||
}
|
||||
|
||||
return new HttpClient();
|
||||
}
|
||||
|
||||
private void TrimKey(JsonWebKey key, byte[] existing)
|
||||
{
|
||||
byte[] signRemoved = new byte[existing.Length - 1];
|
||||
Buffer.BlockCopy(existing, 1, signRemoved, 0, existing.Length - 1);
|
||||
string withSignRemoved = Base64UrlEncoder.Encode(signRemoved);
|
||||
key.N = withSignRemoved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,12 +11,9 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry
|
||||
{
|
||||
public static class CloudFoundryTokenValidator
|
||||
|
@ -28,8 +24,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry
|
|||
{
|
||||
return issuer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Steeltoe.Security.Authentication.CloudFoundryCore.Test")]
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OAuth" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(AspNetCoreVersion)" />
|
||||
|
@ -24,6 +24,17 @@
|
|||
<PackageReference Include="Steeltoe.CloudFoundry.Connector" Version="$(SteeltoeConnectorVersion)" />
|
||||
<PackageReference Include="Steeltoe.Common.Http" Version="$(SteeltoeCommonVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.Owin.Infrastructure;
|
||||
using Microsoft.Owin.Security;
|
||||
|
@ -22,21 +20,45 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
||||
{
|
||||
class OpenIDConnectAuthenticationHandler : AuthenticationHandler<OpenIDConnectOptions>
|
||||
public class OpenIDConnectAuthenticationHandler : AuthenticationHandler<OpenIDConnectOptions>
|
||||
{
|
||||
/*
|
||||
* Invoked for every request. As this is passive middleware, we only want to branch off
|
||||
* the authentication flow if the request being invoked is the callback path we gave as a redirect
|
||||
* uri to the auth flow when invoking the IDP
|
||||
*/
|
||||
public override async Task<bool> InvokeAsync()
|
||||
{
|
||||
if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path)
|
||||
{
|
||||
var ticket = await AuthenticateAsync();
|
||||
if (ticket != null)
|
||||
{
|
||||
Context.Authentication.SignIn(ticket.Properties, ticket.Identity);
|
||||
Response.Redirect(ticket.Properties.RedirectUri);
|
||||
|
||||
// Short-circuit, stopping rest of owin pipeline.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to see here, please disperse.
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
|
||||
{
|
||||
|
||||
var code = Request.Query["code"];
|
||||
Debug.WriteLine("Received an authorization code from IDP: " + code);
|
||||
Debug.WriteLine("== exchanging for token ==");
|
||||
// ASP.Net Identity requires the NameIdentitifer field to be set or it won't
|
||||
|
||||
// ASP.Net Identity requires the NameIdentitifer field to be set or it won't
|
||||
// accept the external login (AuthenticationManagerExtensions.GetExternalLoginInfo)
|
||||
var identity = await TokenExchanger.ExchangeCodeForToken(code, Options);
|
||||
|
||||
var properties = Options.StateDataFormat.Unprotect(Request.Query["state"]);
|
||||
|
||||
//return Task.FromResult(new AuthenticationTicket(identity, properties));
|
||||
// return Task.FromResult(new AuthenticationTicket(identity, properties));
|
||||
var ticket = new AuthenticationTicket(identity, properties);
|
||||
return ticket;
|
||||
}
|
||||
|
@ -69,33 +91,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
return Task.FromResult<object>(null);
|
||||
}
|
||||
|
||||
|
||||
protected override Task InitializeCoreAsync()
|
||||
{
|
||||
return base.InitializeCoreAsync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoked for every request. As this is passive middleware, we only want to branch off
|
||||
* the authentication flow if the request being invoked is the callback path we gave as a redirect
|
||||
* uri to the auth flow when invoking the IDP
|
||||
*/
|
||||
public override async Task<bool> InvokeAsync()
|
||||
{
|
||||
if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path)
|
||||
{
|
||||
var ticket = await AuthenticateAsync();
|
||||
if (ticket != null)
|
||||
{
|
||||
Context.Authentication.SignIn(ticket.Properties, ticket.Identity);
|
||||
Response.Redirect(ticket.Properties.RedirectUri);
|
||||
|
||||
// Short-circuit, stopping rest of owin pipeline.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Nothing to see here, please disperse.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
|
@ -32,9 +30,11 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
|
||||
if (options.StateDataFormat == null)
|
||||
{
|
||||
var dataProtector = app.CreateDataProtector(typeof(OpenIDConnectAuthenticationMiddleware).FullName,
|
||||
var dataProtector = app.CreateDataProtector(
|
||||
typeof(OpenIDConnectAuthenticationMiddleware).FullName,
|
||||
options.AuthenticationType);
|
||||
|
||||
options.StateDataFormat = new PropertiesDataFormat(dataProtector);
|
||||
|
@ -47,4 +47,3 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Owin;
|
||||
using System.Net;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
|
@ -21,7 +19,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
{
|
||||
public class OpenIDConnectOptions : AuthenticationOptions
|
||||
{
|
||||
public OpenIDConnectOptions() : base(Constants.DefaultAuthenticationType)
|
||||
public OpenIDConnectOptions()
|
||||
: base(Constants.DefaultAuthenticationType)
|
||||
{
|
||||
Description.Caption = Constants.DefaultAuthenticationType;
|
||||
CallbackPath = new PathString("/signin-oidc");
|
||||
|
|
|
@ -21,7 +21,18 @@
|
|||
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="$(OwinOAuthVerions)" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="$(JwtTokensVerions)" />
|
||||
<PackageReference Include="System.Net.Http" Version="$(HttpClientVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
@ -30,9 +31,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
{
|
||||
string redirect_url = "https://" + options.AppHost;
|
||||
if (options.AppPort != 0)
|
||||
{
|
||||
redirect_url = redirect_url + ":" + options.AppPort + options.CallbackPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect_url = redirect_url + options.CallbackPath;
|
||||
}
|
||||
|
||||
var hostName = options.AuthDomain;
|
||||
var pairs = new[]
|
||||
|
@ -55,11 +60,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
|
||||
var byteArray = Encoding.ASCII.GetBytes(options.ClientID + ":" + options.ClientSecret);
|
||||
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
|
||||
|
||||
|
||||
var response = await client.PostAsync(targetUrl, content);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
|
@ -76,7 +79,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
foreach (var claim in securityToken.Claims)
|
||||
{
|
||||
Debug.WriteLine(claim.Type + " : " + claim.Value);
|
||||
// claimsId.AddClaim(claim);
|
||||
|
||||
// claimsId.AddClaim(claim);
|
||||
}
|
||||
|
||||
claimsId.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId));
|
||||
|
@ -96,4 +100,3 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,17 +11,15 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.Owin.Infrastructure;
|
||||
using System;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
||||
{
|
||||
internal static class UriUtility
|
||||
{
|
||||
internal static String CalculateFullRedirectUri(OpenIDConnectOptions options)
|
||||
internal static string CalculateFullRedirectUri(OpenIDConnectOptions options)
|
||||
{
|
||||
var uri = options.AuthDomain + "/" + Constants.EndPointOAuthAuthorize;
|
||||
|
||||
|
@ -39,8 +39,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Owin
|
|||
{
|
||||
uri = uri + ":" + options.AppPort.ToString();
|
||||
}
|
||||
|
||||
return uri + options.CallbackPath;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
@ -29,18 +30,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
|
||||
public CloudFoundryClientTokenResolver(CloudFoundryOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException("options null");
|
||||
}
|
||||
Options = options;
|
||||
|
||||
Options = options ?? throw new ArgumentNullException("options null");
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<string> GetAccessToken()
|
||||
{
|
||||
HttpRequestMessage requestMessage = GetTokenRequestMessage();
|
||||
|
||||
|
||||
RemoteCertificateValidationCallback prevValidator = ServicePointManager.ServerCertificateValidationCallback;
|
||||
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
|
||||
|
||||
|
@ -74,8 +70,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
internal protected virtual HttpRequestMessage GetTokenRequestMessage()
|
||||
protected internal virtual HttpRequestMessage GetTokenRequestMessage()
|
||||
{
|
||||
var tokenRequestParameters = GetTokenRequestParameters();
|
||||
|
||||
|
@ -88,8 +83,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
return requestMessage;
|
||||
}
|
||||
|
||||
|
||||
internal protected virtual Dictionary<string, string> GetTokenRequestParameters()
|
||||
protected internal virtual Dictionary<string, string> GetTokenRequestParameters()
|
||||
{
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
|
@ -97,17 +91,25 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{ "client_secret", Options.ClientSecret },
|
||||
{ "response_type", "token" },
|
||||
{ "grant_type", "client_credentials" },
|
||||
{ "scope", Options.RequiredScopes == null ? "openid" :
|
||||
string.Join(" ",Options.RequiredScopes) },
|
||||
{
|
||||
"scope", Options.RequiredScopes == null ? "openid" :
|
||||
string.Join(" ", Options.RequiredScopes)
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
internal protected string GetEncoded(string user, string password)
|
||||
protected internal string GetEncoded(string user, string password)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
user = string.Empty;
|
||||
}
|
||||
|
||||
if (password == null)
|
||||
{
|
||||
password = string.Empty;
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(Encoding.ASCII.GetBytes(user + ":" + password));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
@ -17,15 +18,12 @@ using System.Linq;
|
|||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
public class CloudFoundryJwt
|
||||
{
|
||||
|
||||
public static void OnTokenValidatedAddClaims(ClaimsIdentity identity,JwtSecurityToken jwt)
|
||||
public static void OnTokenValidatedAddClaims(ClaimsIdentity identity, JwtSecurityToken jwt)
|
||||
{
|
||||
|
||||
var identifier = GetId(identity);
|
||||
if (!string.IsNullOrEmpty(identifier))
|
||||
{
|
||||
|
@ -58,13 +56,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
else
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, GetClientId(identity), ClaimValueTypes.String, jwt.Issuer));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static string GetGivenName(IIdentity identity)
|
||||
{
|
||||
return GetClaim(identity, "given_name");
|
||||
|
@ -79,10 +73,12 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
return GetClaim(identity, "email");
|
||||
}
|
||||
|
||||
private static string GetName(IIdentity identity)
|
||||
{
|
||||
return GetClaim(identity, "user_name");
|
||||
}
|
||||
|
||||
private static string GetId(IIdentity identity)
|
||||
{
|
||||
return GetClaim(identity, "user_id");
|
||||
|
@ -93,8 +89,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
return GetClaim(identity, "client_id");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static string GetClaim(IIdentity identity, string claim)
|
||||
{
|
||||
var claims = identity as ClaimsIdentity;
|
||||
|
@ -102,11 +96,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var idClaim = claims.FindFirst(claim);
|
||||
if (idClaim == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return idClaim.Value;
|
||||
}
|
||||
|
||||
|
@ -117,11 +113,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var idClaims = claims.FindAll(claim);
|
||||
if (idClaims == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return idClaims.ToArray<Claim>();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,60 +11,75 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
|
||||
public class CloudFoundryOptions //: OAuthOptions
|
||||
public class CloudFoundryOptions
|
||||
{
|
||||
public const string AUTHENTICATION_SCHEME = "CloudFoundry";
|
||||
public const string OAUTH_AUTHENTICATION_SCHEME = "CloudFoundry.OAuth";
|
||||
|
||||
internal const string Default_AuthorizationUri = "/oauth/authorize";
|
||||
internal const string Default_AccessTokenUri = "/oauth/token";
|
||||
internal const string Default_UserInfoUri = "/userinfo";
|
||||
internal const string Default_CheckTokenUri = "/check_token";
|
||||
internal const string Default_JwtTokenKey = "/token_key";
|
||||
|
||||
public const string AUTHENTICATION_SCHEME = "CloudFoundry";
|
||||
public const string OAUTH_AUTHENTICATION_SCHEME = "CloudFoundry.OAuth";
|
||||
|
||||
public string TokenInfoUrl { get; set; }
|
||||
|
||||
public bool ValidateCertificates { get; set; }
|
||||
|
||||
public bool ValidateAudience { get; set; }
|
||||
|
||||
public bool ValidateIssuer { get; set; }
|
||||
|
||||
public bool ValidateLifetime { get; set; }
|
||||
|
||||
public string OAuthServiceUrl { get; set; }
|
||||
|
||||
public string ClientId { get; set; }
|
||||
|
||||
public string ClientSecret { get; set; }
|
||||
|
||||
public string AuthorizationEndpoint { get; set; }
|
||||
|
||||
public string AccessTokenEndpoint { get; set; }
|
||||
|
||||
public string UserInformationEndpoint { get; set; }
|
||||
|
||||
public string TokenInfoEndpoint { get; set; }
|
||||
|
||||
public string JwtKeyEndpoint { get; set; }
|
||||
|
||||
public string[] RequiredScopes { get; set; }
|
||||
|
||||
public string[] AdditionalAudiences { get; set; }
|
||||
|
||||
|
||||
public TokenValidationParameters TokenValidationParameters { get; set; }
|
||||
|
||||
internal CloudFoundryTokenKeyResolver TokenKeyResolver { get; set; }
|
||||
|
||||
internal CloudFoundryTokenValidator TokenValidator { get; set; }
|
||||
|
||||
|
||||
|
||||
public CloudFoundryOptions() :this ( System.Environment.GetEnvironmentVariable("sso_auth_domain") )
|
||||
public CloudFoundryOptions()
|
||||
: this(System.Environment.GetEnvironmentVariable("sso_auth_domain"))
|
||||
{
|
||||
ClientId = System.Environment.GetEnvironmentVariable("sso_client_id");
|
||||
ClientSecret = System.Environment.GetEnvironmentVariable("sso_client_secret");
|
||||
|
||||
ClientId = System.Environment.GetEnvironmentVariable("sso_client_id");
|
||||
ClientSecret = System.Environment.GetEnvironmentVariable("sso_client_secret");
|
||||
}
|
||||
public CloudFoundryOptions(string authDomain, string clientId, string clientSecret) : this(authDomain)
|
||||
|
||||
public CloudFoundryOptions(string authDomain, string clientId, string clientSecret)
|
||||
: this(authDomain)
|
||||
{
|
||||
ClientId = clientId;
|
||||
ClientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public CloudFoundryOptions(string authUrl)
|
||||
{
|
||||
//CallbackPath = new PathString("/signin-cloudfoundry");
|
||||
// CallbackPath = new PathString("/signin-cloudfoundry");
|
||||
OAuthServiceUrl = authUrl;
|
||||
AuthorizationEndpoint = authUrl + Default_AuthorizationUri;
|
||||
AccessTokenEndpoint = authUrl + Default_AccessTokenUri;
|
||||
|
@ -79,7 +96,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
TokenValidationParameters = GetTokenValidationParameters(this);
|
||||
}
|
||||
|
||||
|
||||
internal static TokenValidationParameters GetTokenValidationParameters(CloudFoundryOptions options)
|
||||
{
|
||||
if (options.TokenValidationParameters != null)
|
||||
|
@ -88,7 +104,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
}
|
||||
|
||||
var parameters = new TokenValidationParameters();
|
||||
options.TokenKeyResolver = options.TokenKeyResolver ?? new CloudFoundryTokenKeyResolver(options);
|
||||
options.TokenKeyResolver = options.TokenKeyResolver ?? new CloudFoundryTokenKeyResolver(options);
|
||||
options.TokenValidator = options.TokenValidator ?? new CloudFoundryTokenValidator(options);
|
||||
options.TokenValidationParameters = parameters;
|
||||
|
||||
|
@ -96,14 +112,11 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
parameters.ValidateIssuer = options.ValidateIssuer;
|
||||
parameters.ValidateLifetime = options.ValidateLifetime;
|
||||
|
||||
|
||||
parameters.IssuerSigningKeyResolver = options.TokenKeyResolver.ResolveSigningKey;
|
||||
parameters.IssuerValidator = options.TokenValidator.ValidateIssuer;
|
||||
parameters.AudienceValidator = options.TokenValidator.ValidateAudience;
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
|
@ -31,18 +32,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
|
||||
public CloudFoundryTokenKeyResolver(CloudFoundryOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException("options null");
|
||||
}
|
||||
Options = options;
|
||||
Options = options ?? throw new ArgumentNullException("options null");
|
||||
Resolved = new Dictionary<string, SecurityKey>();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<SecurityKey> ResolveSigningKey(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
|
||||
{
|
||||
SecurityKey resolved = null;
|
||||
if (Resolved.TryGetValue(kid, out resolved))
|
||||
if (Resolved.TryGetValue(kid, out SecurityKey resolved))
|
||||
{
|
||||
return new List<SecurityKey> { resolved };
|
||||
}
|
||||
|
@ -56,37 +52,27 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
Resolved[key.Kid] = key;
|
||||
}
|
||||
}
|
||||
|
||||
if (Resolved.TryGetValue(kid, out resolved))
|
||||
{
|
||||
return new List<SecurityKey> { resolved };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public JsonWebKey FixupKey(JsonWebKey key)
|
||||
{
|
||||
|
||||
byte[] existing = Base64UrlEncoder.DecodeBytes(key.N);
|
||||
TrimKey(key, existing);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
private void TrimKey(JsonWebKey key, byte[] existing)
|
||||
{
|
||||
byte[] signRemoved = new byte[existing.Length -1];
|
||||
Buffer.BlockCopy(existing, 1, signRemoved, 0, existing.Length - 1);
|
||||
string withSignRemoved = Base64UrlEncoder.Encode(signRemoved);
|
||||
key.N = withSignRemoved;
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<JsonWebKeySet> FetchKeySet()
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, Options.JwtKeyEndpoint);
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
|
||||
RemoteCertificateValidationCallback prevValidator = null;
|
||||
|
||||
using (var handler = new HttpClientHandler())
|
||||
|
@ -101,9 +87,9 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
response = await client.SendAsync(requestMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error getting keys to validate token:" + ex.Message );
|
||||
throw new Exception("Error getting keys to validate token:" + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -117,16 +103,20 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual JsonWebKeySet GetJsonWebKeySet(string json)
|
||||
{
|
||||
return new JsonWebKeySetEx(json);
|
||||
|
||||
return new JsonWebKeySetEx(json);
|
||||
}
|
||||
|
||||
|
||||
private void TrimKey(JsonWebKey key, byte[] existing)
|
||||
{
|
||||
byte[] signRemoved = new byte[existing.Length - 1];
|
||||
Buffer.BlockCopy(existing, 1, signRemoved, 0, existing.Length - 1);
|
||||
string withSignRemoved = Base64UrlEncoder.Encode(signRemoved);
|
||||
key.N = withSignRemoved;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
|
@ -25,19 +26,37 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
public class CloudFoundryTokenValidator
|
||||
{
|
||||
|
||||
public CloudFoundryOptions Options { get; internal protected set; }
|
||||
|
||||
private JwtSecurityTokenHandler _handler = new JwtSecurityTokenHandler();
|
||||
|
||||
public CloudFoundryTokenValidator(CloudFoundryOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException("options null");
|
||||
}
|
||||
Options = options;
|
||||
Options = options ?? throw new ArgumentNullException("options null");
|
||||
}
|
||||
|
||||
public static void ThrowJwtException(string exeptionMessage, string message)
|
||||
{
|
||||
Console.Out.WriteLine("error: " + exeptionMessage + " " + message);
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
var headers = WebOperationContext.Current.OutgoingResponse.Headers;
|
||||
|
||||
// https://tools.ietf.org/html/rfc6750 - "WWW-Authenticate", "Bearer error=\"insufficient_scope\"");
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
message = "invalid_token";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(exeptionMessage))
|
||||
{
|
||||
exeptionMessage = message;
|
||||
}
|
||||
|
||||
headers.Add(HttpResponseHeader.WwwAuthenticate, string.Format("Bearer realm=\"default\",error=\"{0}\",error_description=\"{1}\"", message, Regex.Replace(exeptionMessage, @"\s+", " ")));
|
||||
}
|
||||
|
||||
throw new WebFaultException<string>(exeptionMessage ?? message, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
public virtual string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
|
||||
|
@ -46,6 +65,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
return issuer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -62,42 +82,21 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
bool found = Options.AdditionalAudiences.Any(x => x.Equals(audience));
|
||||
if (found)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method validate scopes provided in configuration,
|
||||
/// to perform scope based Authorization
|
||||
/// </summary>
|
||||
/// <param name="validJwt"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool ValidateScopes(JwtSecurityToken validJwt)
|
||||
{
|
||||
|
||||
if (Options.RequiredScopes == null || Options.RequiredScopes.Count<string>() == 0)
|
||||
return true; // nocheck
|
||||
|
||||
if (!validJwt.Claims.Any(x => x.Type.Equals("scope") || x.Type.Equals("authorities")))
|
||||
return false;// no scopes at all
|
||||
|
||||
bool found = false;
|
||||
foreach (Claim claim in validJwt.Claims)
|
||||
{
|
||||
if (claim.Type.Equals("scope") || claim.Type.Equals("authorities")
|
||||
&& Options.RequiredScopes.Any(x => x.Equals(claim.Value)))
|
||||
return true;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
public virtual ClaimsPrincipal ValidateToken(string token)
|
||||
public virtual ClaimsPrincipal ValidateToken(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
SecurityToken validatedToken = null;
|
||||
ClaimsPrincipal principal = null;
|
||||
|
@ -111,41 +110,54 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("ValidateToken fails:" + ex.Message);
|
||||
throwJwtException(ex.Message, "invalid_token");
|
||||
ThrowJwtException(ex.Message, "invalid_token");
|
||||
}
|
||||
|
||||
if (validJwt == null || principal == null)
|
||||
{
|
||||
ThrowJwtException(null, "invalid_token");
|
||||
}
|
||||
|
||||
if (validJwt == null || principal == null )
|
||||
throwJwtException(null, "invalid_token");
|
||||
|
||||
CloudFoundryJwt.OnTokenValidatedAddClaims((ClaimsIdentity)principal.Identity, validJwt);
|
||||
|
||||
|
||||
bool validScopes = ValidateScopes(validJwt);
|
||||
if ( !validScopes)
|
||||
throwJwtException(null, "insufficient_scope");
|
||||
|
||||
if (!validScopes)
|
||||
{
|
||||
ThrowJwtException(null, "insufficient_scope");
|
||||
}
|
||||
|
||||
return principal;
|
||||
}
|
||||
|
||||
|
||||
public static void throwJwtException (string exeptionMessage, string message)
|
||||
/// <summary>
|
||||
/// This method validate scopes provided in configuration,
|
||||
/// to perform scope based Authorization
|
||||
/// </summary>
|
||||
/// <param name="validJwt">JSON Web token</param>
|
||||
/// <returns>true if scopes validated</returns>
|
||||
protected virtual bool ValidateScopes(JwtSecurityToken validJwt)
|
||||
{
|
||||
Console.Out.WriteLine("error: " + exeptionMessage + " " + message );
|
||||
if (WebOperationContext.Current != null)
|
||||
if (Options.RequiredScopes == null || Options.RequiredScopes.Count<string>() == 0)
|
||||
{
|
||||
var headers = WebOperationContext.Current.OutgoingResponse.Headers;
|
||||
|
||||
//https://tools.ietf.org/html/rfc6750 - "WWW-Authenticate", "Bearer error=\"insufficient_scope\"");
|
||||
if (string.IsNullOrEmpty(message))
|
||||
message = "invalid_token";
|
||||
|
||||
if (string.IsNullOrEmpty(exeptionMessage))
|
||||
exeptionMessage = message;
|
||||
|
||||
headers.Add(HttpResponseHeader.WwwAuthenticate, string.Format("Bearer realm=\"default\",error=\"{0}\",error_description=\"{1}\"", message, Regex.Replace(exeptionMessage, @"\s+", " ")));
|
||||
return true; // nocheck
|
||||
}
|
||||
|
||||
throw new WebFaultException<string>(exeptionMessage == null ? message : exeptionMessage, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
if (!validJwt.Claims.Any(x => x.Type.Equals("scope") || x.Type.Equals("authorities")))
|
||||
{
|
||||
return false; // no scopes at all
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
foreach (Claim claim in validJwt.Claims)
|
||||
{
|
||||
if (claim.Type.Equals("scope") || (claim.Type.Equals("authorities")
|
||||
&& Options.RequiredScopes.Any(x => x.Equals(claim.Value))))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
|
@ -17,14 +18,17 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
public class JsonWebKeySetEx : JsonWebKeySet
|
||||
{
|
||||
public JsonWebKeySetEx(string json) : base(json)
|
||||
public JsonWebKeySetEx(string json)
|
||||
: base(json)
|
||||
{
|
||||
// try to see if its just one key not the set
|
||||
if (Keys == null || Keys.Count == 0)
|
||||
if (Keys == null || Keys.Count == 0)
|
||||
{
|
||||
JsonWebKey key = new JsonWebKey(json);
|
||||
if (key != null)
|
||||
{
|
||||
Keys.Add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,73 +11,76 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
|
||||
using System.Security.Claims;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Web.Hosting;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
public class JwtAuthorizationManager : ServiceAuthorizationManager
|
||||
{
|
||||
|
||||
public CloudFoundryOptions Options { get; internal protected set; }
|
||||
|
||||
|
||||
public JwtAuthorizationManager() : base()
|
||||
{
|
||||
|
||||
public JwtAuthorizationManager()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
protected override bool CheckAccessCore(OperationContext operationContext)
|
||||
{
|
||||
HttpRequestMessageProperty httpRequestMessage;
|
||||
object httpRequestMessageObject;
|
||||
|
||||
if (operationContext.RequestContext.RequestMessage.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
|
||||
if (operationContext.RequestContext.RequestMessage.Properties.TryGetValue(HttpRequestMessageProperty.Name, out object httpRequestMessageObject))
|
||||
{
|
||||
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
|
||||
if (string.IsNullOrEmpty(httpRequestMessage.Headers["Authorization"]))
|
||||
CloudFoundryTokenValidator.throwJwtException("No Authorization header",null);
|
||||
|
||||
{
|
||||
CloudFoundryTokenValidator.ThrowJwtException("No Authorization header", null);
|
||||
}
|
||||
|
||||
// Get Bearer token
|
||||
if (!httpRequestMessage.Headers["Authorization"].StartsWith("Bearer "))
|
||||
CloudFoundryTokenValidator.throwJwtException("No Token", null);
|
||||
|
||||
{
|
||||
CloudFoundryTokenValidator.ThrowJwtException("No Token", null);
|
||||
}
|
||||
|
||||
string jwt = httpRequestMessage.Headers["Authorization"].Split(' ')[1];
|
||||
if (string.IsNullOrEmpty(jwt))
|
||||
CloudFoundryTokenValidator.throwJwtException("Wrong Token Format", null);
|
||||
|
||||
{
|
||||
CloudFoundryTokenValidator.ThrowJwtException("Wrong Token Format", null);
|
||||
}
|
||||
|
||||
// Get SSO Config
|
||||
Options = (Options != null) ? Options : new CloudFoundryOptions();
|
||||
if (Options.OAuthServiceUrl == null || Options.OAuthServiceUrl.Length == 0)
|
||||
CloudFoundryTokenValidator.throwJwtException("SSO Configuration is missing", null);
|
||||
Options = Options ?? new CloudFoundryOptions();
|
||||
if (Options.OAuthServiceUrl == null || Options.OAuthServiceUrl.Length == 0)
|
||||
{
|
||||
CloudFoundryTokenValidator.ThrowJwtException("SSO Configuration is missing", null);
|
||||
}
|
||||
|
||||
|
||||
// Validate Token
|
||||
ClaimsPrincipal claimsPrincipal = Options.TokenValidator.ValidateToken(jwt);
|
||||
// Validate Token
|
||||
ClaimsPrincipal claimsPrincipal = Options.TokenValidator.ValidateToken(jwt);
|
||||
if (claimsPrincipal == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the Principal created from token
|
||||
SetPrincipal(operationContext, claimsPrincipal);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ClaimsPrincipal GetPrincipal(OperationContext operationContext)
|
||||
{
|
||||
var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
|
||||
return properties["Principal"] as ClaimsPrincipal;
|
||||
}
|
||||
|
||||
private void SetPrincipal(OperationContext operationContext, ClaimsPrincipal principal)
|
||||
{
|
||||
|
@ -94,20 +99,12 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
HttpContext cur = HttpContext.Current;
|
||||
if (cur != null)
|
||||
{
|
||||
cur.User = principal;
|
||||
}
|
||||
}
|
||||
//Thread.CurrentPrincipal = principal;
|
||||
|
||||
|
||||
|
||||
// Thread.CurrentPrincipal = principal;
|
||||
}
|
||||
|
||||
protected ClaimsPrincipal GetPrincipal(OperationContext operationContext)
|
||||
{
|
||||
var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
|
||||
return properties["Principal"] as ClaimsPrincipal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
@ -20,18 +21,19 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
public class JwtHeaderEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
|
||||
{
|
||||
const string SSOPropertyName = "ssoName";
|
||||
private const string SSOPropertyName = "ssoName";
|
||||
|
||||
[ConfigurationProperty(SSOPropertyName)]
|
||||
public string SsoName
|
||||
public string SsoName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)base[SSOPropertyName];
|
||||
return (string)this[SSOPropertyName];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[SSOPropertyName] = value;
|
||||
this[SSOPropertyName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,37 +42,28 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
get { return typeof(JwtHeaderEndpointBehavior); }
|
||||
}
|
||||
|
||||
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
|
||||
{
|
||||
clientRuntime.ClientMessageInspectors.Add(new JwtHeaderMessageInspector());
|
||||
}
|
||||
|
||||
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
|
||||
{
|
||||
}
|
||||
|
||||
public void Validate(ServiceEndpoint endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
protected override object CreateBehavior()
|
||||
{
|
||||
// Create the endpoint behavior that will insert the message
|
||||
// inspector into the client runtime
|
||||
return new JwtHeaderEndpointBehavior();
|
||||
}
|
||||
|
||||
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
|
||||
{
|
||||
clientRuntime.ClientMessageInspectors.Add(new JwtHeaderMessageInspector());
|
||||
|
||||
}
|
||||
|
||||
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Validate(ServiceEndpoint endpoint)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ServiceModel.Channels;
|
||||
|
@ -17,10 +18,9 @@ using System.ServiceModel.Dispatcher;
|
|||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
|
||||
public class JwtHeaderMessageInspector : IClientMessageInspector
|
||||
{
|
||||
private string _token;
|
||||
private string _token;
|
||||
|
||||
public JwtHeaderMessageInspector()
|
||||
{
|
||||
|
@ -28,14 +28,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
|
||||
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
|
||||
{
|
||||
|
||||
if (_token == null)
|
||||
{
|
||||
_token = GetAccessToken();
|
||||
|
||||
}
|
||||
|
||||
HttpRequestMessageProperty httpRequestMessage;
|
||||
object httpRequestMessageObject;
|
||||
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
|
||||
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out object httpRequestMessageObject))
|
||||
{
|
||||
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
|
||||
}
|
||||
|
@ -46,12 +45,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
}
|
||||
|
||||
if (httpRequestMessage != null)
|
||||
{
|
||||
httpRequestMessage.Headers.Add("Authorization", string.Format("Bearer {0}", _token));
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
|
||||
{
|
||||
HttpResponseMessageProperty httpResponse;
|
||||
|
@ -59,34 +59,27 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
httpResponse = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
|
||||
}
|
||||
//could get here refreshed token
|
||||
|
||||
|
||||
// could get here refreshed token
|
||||
}
|
||||
|
||||
|
||||
private string GetAccessToken()
|
||||
private string GetAccessToken()
|
||||
{
|
||||
CloudFoundryOptions options = new CloudFoundryOptions();
|
||||
|
||||
|
||||
CloudFoundryOptions options = new CloudFoundryOptions();
|
||||
|
||||
CloudFoundryClientTokenResolver tokenResolver = new CloudFoundryClientTokenResolver(options);
|
||||
CloudFoundryClientTokenResolver tokenResolver = new CloudFoundryClientTokenResolver(options);
|
||||
|
||||
try
|
||||
{
|
||||
string accessToken = tokenResolver.GetAccessToken().GetAwaiter().GetResult();
|
||||
|
||||
return accessToken;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Console.Out.WriteLine(ex.Message + ex.StackTrace);
|
||||
throw new Exception("Cannont obtain the Access Token" + ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,19 +11,15 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Security.Principal;
|
||||
using System.Net;
|
||||
using System.ServiceModel.Web;
|
||||
using System.Threading;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public class PrincipalPermissionEnvAttribute : CodeAccessSecurityAttribute
|
||||
|
@ -38,27 +36,29 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
_authenticated = true;
|
||||
}
|
||||
|
||||
|
||||
public override IPermission CreatePermission()
|
||||
{
|
||||
if (Unrestricted)
|
||||
{
|
||||
return new PrincipalPermission(PermissionState.Unrestricted);
|
||||
}
|
||||
|
||||
string matchACL = Environment.GetEnvironmentVariable(Role);
|
||||
if (String.IsNullOrEmpty(matchACL))
|
||||
CloudFoundryTokenValidator.throwJwtException("Configuration for not provided for Role: " + Role, "insufficient_scope");
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(matchACL))
|
||||
{
|
||||
CloudFoundryTokenValidator.ThrowJwtException("Configuration for not provided for Role: " + Role, "insufficient_scope");
|
||||
}
|
||||
|
||||
IPrincipal principal = Thread.CurrentPrincipal;
|
||||
|
||||
if (principal.IsInRole(matchACL))
|
||||
{
|
||||
return new PrincipalPermission(principal.Identity.Name, matchACL, _authenticated);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
Console.Out.WriteLine("Access denied user is not in Role: " + Role);
|
||||
CloudFoundryTokenValidator.throwJwtException("Access denied user is not in Role: " + Role, "insufficient_scope");
|
||||
CloudFoundryTokenValidator.ThrowJwtException("Access denied user is not in Role: " + Role, "insufficient_scope");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Security;
|
||||
|
@ -24,11 +25,11 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
public string Scope { get; set; }
|
||||
|
||||
public ScopePermission(string name, string scope)
|
||||
public ScopePermission(string name, string scope)
|
||||
{
|
||||
Scope = scope;
|
||||
}
|
||||
|
||||
|
||||
public bool IsUnrestricted()
|
||||
{
|
||||
return true;
|
||||
|
@ -41,15 +42,16 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
if (principal == null || !principal.HasClaim("scope", this.Scope))
|
||||
{
|
||||
Console.Out.WriteLine("Access denied token is not in Scope: " + Scope);
|
||||
CloudFoundryTokenValidator.throwJwtException("Access denied token does not have Scope: " + Scope,"insufficient_scope");
|
||||
CloudFoundryTokenValidator.ThrowJwtException("Access denied token does not have Scope: " + Scope, "insufficient_scope");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IPermission Intersect(IPermission target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ScopePermission(null, Scope);
|
||||
}
|
||||
|
@ -57,19 +59,23 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
public bool IsSubsetOf(IPermission target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IPermission Union(IPermission target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ScopePermission(null, Scope);
|
||||
}
|
||||
|
||||
|
||||
public void FromXml(SecurityElement e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -9,22 +11,18 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public class ScopePermissionAttribute : CodeAccessSecurityAttribute
|
||||
{
|
||||
|
||||
public string ConfigurationName { get; set; }
|
||||
|
||||
public string Scope { get; set; }
|
||||
|
@ -34,7 +32,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
public override IPermission CreatePermission()
|
||||
{
|
||||
string scope = null;
|
||||
|
@ -45,7 +42,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Wcf
|
|||
|
||||
scope = scope ?? Scope;
|
||||
|
||||
return new ScopePermission(Thread.CurrentPrincipal.Identity.Name, scope);
|
||||
return new ScopePermission(Thread.CurrentPrincipal.Identity.Name, scope);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="$(JwtTokensVerions)" />
|
||||
<PackageReference Include="System.Net.Http" Version="$(HttpClientVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -28,6 +31,14 @@
|
|||
<Reference Include="System.ServiceModel.Web" />
|
||||
<Reference Include="System.Web" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2015 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using StackExchange.Redis;
|
||||
|
@ -22,7 +20,9 @@ namespace Steeltoe.Security.DataProtection.Redis
|
|||
public class CloudFoundryRedisXmlRepository : RedisXmlRepository
|
||||
{
|
||||
private const string DataProtectionKeysName = "DataProtection-Keys";
|
||||
public CloudFoundryRedisXmlRepository(IConnectionMultiplexer redis) : base( () => redis.GetDatabase(), DataProtectionKeysName)
|
||||
|
||||
public CloudFoundryRedisXmlRepository(IConnectionMultiplexer redis)
|
||||
: base(() => redis.GetDatabase(), DataProtectionKeysName)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2015 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
||||
|
@ -25,16 +23,15 @@ using System;
|
|||
|
||||
namespace Steeltoe.Security.DataProtection
|
||||
{
|
||||
|
||||
public static class RedisDataProtectionBuilderExtensions
|
||||
{
|
||||
|
||||
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.Services.TryAddSingleton<IXmlRepository, CloudFoundryRedisXmlRepository>();
|
||||
|
||||
builder.Services.AddSingleton<IConfigureOptions<KeyManagementOptions>>((p) =>
|
||||
|
|
|
@ -16,9 +16,20 @@
|
|||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="$(AspNetCoreDataProtectionRedisVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
|
||||
"settings": {
|
||||
"documentationRules": {
|
||||
"copyrightText": "Copyright {copyrightYear} the original author or authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.",
|
||||
"xmlHeader": false,
|
||||
"variables": {
|
||||
"copyrightYear": "2017"
|
||||
},
|
||||
"documentExposedElements": false,
|
||||
"documentInternalElements": false,
|
||||
"documentPrivateElements": false
|
||||
},
|
||||
"indentation": {
|
||||
"useTabs": false,
|
||||
"indentationSize": 4
|
||||
},
|
||||
"namingRules": {
|
||||
},
|
||||
"orderingRules": {
|
||||
"usingDirectivesPlacement": "outsideNamespace",
|
||||
"systemUsingDirectivesFirst": false
|
||||
},
|
||||
"readabilityRules": {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,14 +11,12 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Xunit;
|
||||
using System;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
|
@ -28,7 +25,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
[Fact]
|
||||
public async void AddCloudFoundryOAuthAuthentication_AddsIntoPipeline()
|
||||
{
|
||||
|
||||
var builder = new WebHostBuilder().UseStartup<TestServerStartup>().UseEnvironment("development");
|
||||
using (var server = new TestServer(builder))
|
||||
{
|
||||
|
@ -36,14 +32,13 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
var result = await client.GetAsync("http://localhost/");
|
||||
Assert.Equal(HttpStatusCode.Redirect, result.StatusCode);
|
||||
var location = result.Headers.Location.ToString();
|
||||
Assert.StartsWith( "http://default_oauthserviceurl/oauth/authorize", location);
|
||||
Assert.StartsWith("http://default_oauthserviceurl/oauth/authorize", location);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void AddCloudFoundryJwtBearerAuthentication_AddsIntoPipeline()
|
||||
{
|
||||
|
||||
var builder = new WebHostBuilder().UseStartup<TestServerJwtStartup>().UseEnvironment("development");
|
||||
using (var server = new TestServer(builder))
|
||||
{
|
||||
|
@ -51,14 +46,11 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
var result = await client.GetAsync("http://localhost/");
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void AddCloudFoundryOAuthAuthentication_AddsIntoPipeline_UsesSSOInfo()
|
||||
{
|
||||
|
||||
|
||||
var app = @"
|
||||
{
|
||||
'cf_api': 'https://api.system.testcloud.com',
|
||||
|
@ -105,7 +97,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Environment.SetEnvironmentVariable("VCAP_APPLICATION", app);
|
||||
Environment.SetEnvironmentVariable("VCAP_SERVICES", services);
|
||||
|
||||
|
||||
var builder = new WebHostBuilder().UseStartup<TestServerStartup>().UseEnvironment("development");
|
||||
using (var server = new TestServer(builder))
|
||||
{
|
||||
|
@ -118,11 +109,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
|
||||
Environment.SetEnvironmentVariable("VCAP_APPLICATION", null);
|
||||
Environment.SetEnvironmentVariable("VCAP_SERVICES", null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Steeltoe.Common;
|
||||
|
@ -30,10 +28,12 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
if (Platform.IsFullFramework)
|
||||
{
|
||||
Assert.Null(result1);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.NotNull(result1);
|
||||
}
|
||||
|
||||
var result2 = CloudFoundryHelper.GetBackChannelHandler(true);
|
||||
Assert.Null(result2);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
[Fact]
|
||||
public void GetExpTime_FindsTime()
|
||||
{
|
||||
var info =TestHelpers.GetValidTokenInfoRequestResponse();
|
||||
var info = TestHelpers.GetValidTokenInfoRequestResponse();
|
||||
var payload = JObject.Parse(info);
|
||||
var dateTime = CloudFoundryHelper.GetExpTime(payload);
|
||||
Assert.Equal(new DateTime(2016, 9, 2, 8, 04, 23, DateTimeKind.Utc), dateTime);
|
||||
|
@ -55,6 +55,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
var dateTime = CloudFoundryHelper.GetIssueTime(payload);
|
||||
Assert.Equal(new DateTime(2016, 9, 1, 20, 04, 23, DateTimeKind.Utc), dateTime);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetScopes_FindsScopes()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Steeltoe.CloudFoundry.Connector.Services;
|
||||
|
@ -23,7 +21,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
public class CloudFoundryJwtBearerConfigurerTest
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void Configure_NoServiceInfo_ReturnsExpected()
|
||||
{
|
||||
|
@ -36,7 +33,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Null(jwtOpts.BackchannelHttpHandler);
|
||||
Assert.NotNull(jwtOpts.TokenValidationParameters);
|
||||
Assert.Equal(opts.SaveToken, jwtOpts.SaveToken);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -53,8 +49,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Null(jwtOpts.BackchannelHttpHandler);
|
||||
Assert.NotNull(jwtOpts.TokenValidationParameters);
|
||||
Assert.Equal(opts.SaveToken, jwtOpts.SaveToken);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTokenValidationParameters_ReturnsExpected()
|
||||
{
|
||||
|
@ -65,8 +61,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(CloudFoundryTokenValidator.ValidateIssuer, parameters.IssuerValidator);
|
||||
Assert.True(parameters.ValidateLifetime);
|
||||
Assert.NotNull(parameters.IssuerSigningKeyResolver);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Xunit;
|
||||
|
||||
|
@ -20,7 +18,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
public class CloudFoundryJwtBearerOptionsTest
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void DefaultConstructor_SetsupDefaultOptions()
|
||||
{
|
||||
|
@ -30,7 +27,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(CloudFoundryDefaults.AuthenticationScheme, opts.ClaimsIssuer);
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.JwtTokenKey, opts.JwtKeyUrl);
|
||||
Assert.True(opts.SaveToken);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,65 +11,46 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Xunit;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
|
||||
public class CloudFoundryOAuthHandlerTest
|
||||
{
|
||||
|
||||
private MyTestCloudFoundryHandler GetTestHandler(CloudFoundryOAuthOptions options)
|
||||
{
|
||||
LoggerFactory loggerFactory = new LoggerFactory();
|
||||
IOptionsMonitor<CloudFoundryOAuthOptions> monitor = new MonitorWrapper<CloudFoundryOAuthOptions>(options);
|
||||
UrlEncoder encoder = UrlEncoder.Default;
|
||||
TestClock clock = new TestClock();
|
||||
MyTestCloudFoundryHandler testHandler = new MyTestCloudFoundryHandler(monitor, loggerFactory, encoder, clock);
|
||||
testHandler.InitializeAsync(
|
||||
new AuthenticationScheme(CloudFoundryDefaults.AuthenticationScheme, CloudFoundryDefaults.AuthenticationScheme, typeof(CloudFoundryOAuthHandler)),
|
||||
new DefaultHttpContext()).Wait();
|
||||
return testHandler;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTokenRequestParameters_ReturnsCorrectly()
|
||||
{
|
||||
|
||||
var opts = new CloudFoundryOAuthOptions()
|
||||
{
|
||||
Backchannel = new HttpClient(new TestMessageHandler())
|
||||
};
|
||||
|
||||
|
||||
MyTestCloudFoundryHandler testHandler = GetTestHandler(opts);
|
||||
|
||||
var parameters = testHandler.GetTokenRequestParameters("code", "redirectUri");
|
||||
Assert.NotNull(parameters);
|
||||
|
||||
|
||||
Assert.Equal(parameters["client_id"], opts.ClientId);
|
||||
Assert.Equal( "redirectUri", parameters["redirect_uri"]);
|
||||
Assert.Equal("redirectUri", parameters["redirect_uri"]);
|
||||
Assert.Equal(parameters["client_secret"], opts.ClientSecret);
|
||||
Assert.Equal( "code", parameters["code"]);
|
||||
Assert.Equal( "authorization_code",parameters["grant_type"]);
|
||||
|
||||
Assert.Equal("code", parameters["code"]);
|
||||
Assert.Equal("authorization_code", parameters["grant_type"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -90,15 +70,16 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(HttpMethod.Post, message.Method);
|
||||
|
||||
message.Headers.Accept.Contains(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ExchangeCodeAsync_SendsTokenRequest_ReturnsValidTokenInfo()
|
||||
{
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(TestHelpers.GetValidTokenRequestResponse());
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(TestHelpers.GetValidTokenRequestResponse())
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
HttpClient client = new HttpClient(handler);
|
||||
|
@ -115,7 +96,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(HttpMethod.Post, handler.LastRequest.Method);
|
||||
Assert.Equal(opts.TokenEndpoint.ToLowerInvariant(), handler.LastRequest.RequestUri.ToString().ToLowerInvariant());
|
||||
|
||||
|
||||
Assert.NotNull(resp);
|
||||
Assert.NotNull(resp.Response);
|
||||
Assert.Equal("bearer", resp.TokenType);
|
||||
|
@ -127,8 +107,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
public async void ExchangeCodeAsync_SendsTokenRequest_ReturnsErrorResponse()
|
||||
{
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
|
||||
response.Content = new StringContent("");
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
|
||||
{
|
||||
Content = new StringContent(string.Empty)
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
HttpClient client = new HttpClient(handler);
|
||||
|
@ -145,7 +127,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(HttpMethod.Post, handler.LastRequest.Method);
|
||||
Assert.Equal(opts.TokenEndpoint.ToLowerInvariant(), handler.LastRequest.RequestUri.ToString().ToLowerInvariant());
|
||||
|
||||
|
||||
Assert.NotNull(resp);
|
||||
Assert.NotNull(resp.Error);
|
||||
Assert.Contains("OAuth token endpoint failure", resp.Error.Message);
|
||||
|
@ -155,8 +136,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
public void BuildChallengeUrl_CreatesCorrectUrl()
|
||||
{
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(TestHelpers.GetValidTokenRequestResponse());
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(TestHelpers.GetValidTokenRequestResponse())
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
HttpClient client = new HttpClient(handler);
|
||||
|
@ -191,9 +174,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
var parameters = testHandler.GetTokenInfoRequestParameters(tokens);
|
||||
Assert.NotNull(parameters);
|
||||
|
||||
|
||||
Assert.Equal(parameters["token"], tokens.AccessToken);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -216,15 +197,16 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.Equal(HttpMethod.Post, message.Method);
|
||||
|
||||
message.Headers.Accept.Contains(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void CreateTicketAsync_SendsTokenInfoRequest_ReturnsValidTokenInfo()
|
||||
{
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(TestHelpers.GetValidTokenInfoRequestResponse());
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(TestHelpers.GetValidTokenInfoRequestResponse())
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
HttpClient client = new HttpClient(handler);
|
||||
|
@ -234,7 +216,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
};
|
||||
MyTestCloudFoundryHandler testHandler = GetTestHandler(opts);
|
||||
|
||||
|
||||
var logger = new LoggerFactory().CreateLogger("CreateTicketAsync_SendsTokenRequest");
|
||||
|
||||
ClaimsIdentity identity = new ClaimsIdentity();
|
||||
|
@ -253,107 +234,19 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
identity.HasClaim(ClaimTypes.NameIdentifier, "13bb6841-e4d6-4a9a-876c-9ef13aa61cc7");
|
||||
identity.HasClaim(ClaimTypes.Name, "testssouser");
|
||||
identity.HasClaim("openid", string.Empty);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MyTestCloudFoundryHandler : CloudFoundryOAuthHandler
|
||||
{
|
||||
public MyTestCloudFoundryHandler(
|
||||
IOptionsMonitor<CloudFoundryOAuthOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
private MyTestCloudFoundryHandler GetTestHandler(CloudFoundryOAuthOptions options)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<AuthenticationTicket> TestCreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
return await base.CreateTicketAsync(identity, properties, tokens);
|
||||
}
|
||||
public async Task<OAuthTokenResponse> TestExchangeCodeAsync(string code, string redirectUri)
|
||||
{
|
||||
return await base.ExchangeCodeAsync(code, redirectUri);
|
||||
}
|
||||
|
||||
public string TestBuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
|
||||
{
|
||||
return base.BuildChallengeUrl(properties, redirectUri);
|
||||
LoggerFactory loggerFactory = new LoggerFactory();
|
||||
IOptionsMonitor<CloudFoundryOAuthOptions> monitor = new MonitorWrapper<CloudFoundryOAuthOptions>(options);
|
||||
UrlEncoder encoder = UrlEncoder.Default;
|
||||
TestClock clock = new TestClock();
|
||||
MyTestCloudFoundryHandler testHandler = new MyTestCloudFoundryHandler(monitor, loggerFactory, encoder, clock);
|
||||
testHandler.InitializeAsync(
|
||||
new AuthenticationScheme(CloudFoundryDefaults.AuthenticationScheme, CloudFoundryDefaults.AuthenticationScheme, typeof(CloudFoundryOAuthHandler)),
|
||||
new DefaultHttpContext()).Wait();
|
||||
return testHandler;
|
||||
}
|
||||
}
|
||||
class TestResponse : IHttpResponseFeature
|
||||
{
|
||||
public Stream Body
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasStarted
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public IHeaderDictionary Headers
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public string ReasonPhrase
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public int StatusCode
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -24,7 +22,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
public class CloudFoundryOAuthOptionsTest
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void DefaultConstructor_SetsupDefaultOptions()
|
||||
{
|
||||
|
@ -32,19 +29,17 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
|
||||
string authURL = "http://" + CloudFoundryDefaults.OAuthServiceUrl;
|
||||
Assert.Equal(CloudFoundryDefaults.AuthenticationScheme, opts.ClaimsIssuer);
|
||||
Assert.Equal(CloudFoundryDefaults.ClientId, opts.ClientId );
|
||||
Assert.Equal(CloudFoundryDefaults.ClientSecret, opts.ClientSecret );
|
||||
Assert.Equal(new PathString("/signin-cloudfoundry"), opts.CallbackPath );
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.AuthorizationUri, opts.AuthorizationEndpoint );
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.AccessTokenUri, opts.TokenEndpoint ) ;
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.UserInfoUri, opts.UserInformationEndpoint );
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.CheckTokenUri, opts.TokenInfoUrl) ;
|
||||
Assert.Equal(CloudFoundryDefaults.ClientId, opts.ClientId);
|
||||
Assert.Equal(CloudFoundryDefaults.ClientSecret, opts.ClientSecret);
|
||||
Assert.Equal(new PathString("/signin-cloudfoundry"), opts.CallbackPath);
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.AuthorizationUri, opts.AuthorizationEndpoint);
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.AccessTokenUri, opts.TokenEndpoint);
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.UserInfoUri, opts.UserInformationEndpoint);
|
||||
Assert.Equal(authURL + CloudFoundryDefaults.CheckTokenUri, opts.TokenInfoUrl);
|
||||
Assert.True(opts.ValidateCertificates);
|
||||
Assert.Equal(6, opts.ClaimActions.Count());
|
||||
Assert.Equal(CookieAuthenticationDefaults.AuthenticationScheme, opts.SignInScheme);
|
||||
Assert.True(opts.SaveTokens);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Security.Claims;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
|
@ -27,11 +25,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
[Fact]
|
||||
public void Constructor_ThrowsIfOptionsNull()
|
||||
{
|
||||
|
||||
// Act and Assert
|
||||
var ex = Assert.Throws<ArgumentException>(() => new CloudFoundryTokenKeyResolver(null, null, false));
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveSigningKey_FindsExistingKey()
|
||||
{
|
||||
|
@ -55,8 +52,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
string token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiI0YjM2NmY4MDdlMjU0MzlmYmRkOTEwZDc4ZjcwYzlhMSIsInN1YiI6ImZlNmExYmUyLWM5MTEtNDM3OC05Y2MxLTVhY2Y1NjA1Y2ZjMiIsInNjb3BlIjpbImNsb3VkX2NvbnRyb2xsZXIucmVhZCIsImNsb3VkX2NvbnRyb2xsZXJfc2VydmljZV9wZXJtaXNzaW9ucy5yZWFkIiwidGVzdGdyb3VwIiwib3BlbmlkIl0sImNsaWVudF9pZCI6Im15VGVzdEFwcCIsImNpZCI6Im15VGVzdEFwcCIsImF6cCI6Im15VGVzdEFwcCIsImdyYW50X3R5cGUiOiJhdXRob3JpemF0aW9uX2NvZGUiLCJ1c2VyX2lkIjoiZmU2YTFiZTItYzkxMS00Mzc4LTljYzEtNWFjZjU2MDVjZmMyIiwib3JpZ2luIjoidWFhIiwidXNlcl9uYW1lIjoiZGF2ZSIsImVtYWlsIjoiZGF2ZSIsImF1dGhfdGltZSI6MTQ3MzYxNTU0MSwicmV2X3NpZyI6IjEwZDM1NzEyIiwiaWF0IjoxNDczNjI0MjU1LCJleHAiOjE0NzM2Njc0NTUsImlzcyI6Imh0dHBzOi8vdWFhLnN5c3RlbS50ZXN0Y2xvdWQuY29tL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbImNsb3VkX2NvbnRyb2xsZXIiLCJteVRlc3RBcHAiLCJvcGVuaWQiLCJjbG91ZF9jb250cm9sbGVyX3NlcnZpY2VfcGVybWlzc2lvbnMiXX0.Hth_SXpMAyiTf--U75r40qODlSUr60U730IW28K2VidEltW3lN3_CE7HkSjolRGr-DYuWHRvy3i_EwBfj1WTkBaXL373UzPVvNBnat9Gi-vjz07LwmBohk3baG1mmlL8IoGbQwtsmfUPhmO5C6_M4s9wKmTf9XIZPVo_w7zPJadrXfHLfx6iQob7CYpTTix2VBWya29iL7kmD1J1UDT5YRg2J9XT30iFuL6BvPQTkuGnX3ivDuUOSdxM8Z451i0VJmc0LYFBCLJ-Tz6bJ2d0wrtfsbCfuNtxjmGJevcL2jKQbEoiliYj60qNtZdT-ijGUdZjE9caxQ2nOkDkowacpw";
|
||||
string keyset = "{ 'keys':[{'kid':'legacy-token-key','alg':'SHA256withRSA','value':'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+7xH35bYBppsn54cBW+\nFlrveTe+3L4xl7ix13XK8eBcCmNOyBhNzhks6toDiRjrgw5QW76cFirVRFIVQkiZ\nsUwDyGOax3q8NOJyBFXiplIUScrx8aI0jkY/Yd6ixAc5yBSBfXThy4EF9T0xCyt4\nxWLYNXMRwe88Y+i+MEoLNXWRbhjJm76LN7rsdIxALbS0vJNWUDALWjtE6FeYX6uU\nL9msAzlCQkdnSvwMmr8Ij2O3IVMxHDJXOZinFqt9zVfXwO11o7ZmiskZnRz1/V0f\nvbUQAadkcDEUt1gk9cbrAhiipg8VWDMsC7VUXuekJZjme5f8oWTwpsgP6cTUzwSS\n6wIDAQAB\n-----END PUBLIC KEY-----','kty':'RSA','use':'sig','n':'AJPu8R9+W2AaabJ+eHAVvhZa73k3vty+MZe4sdd1yvHgXApjTsgYTc4ZLOraA4kY64MOUFu+nBYq1URSFUJImbFMA8hjmsd6vDTicgRV4qZSFEnK8fGiNI5GP2HeosQHOcgUgX104cuBBfU9MQsreMVi2DVzEcHvPGPovjBKCzV1kW4YyZu+ize67HSMQC20tLyTVlAwC1o7ROhXmF+rlC/ZrAM5QkJHZ0r8DJq/CI9jtyFTMRwyVzmYpxarfc1X18DtdaO2ZorJGZ0c9f1dH721EAGnZHAxFLdYJPXG6wIYoqYPFVgzLAu1VF7npCWY5nuX/KFk8KbID+nE1M8Ekus=','e':'AQAB'}]}";
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(keyset);
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(keyset)
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
CloudFoundryTokenKeyResolver.Resolved.Clear();
|
||||
|
@ -74,8 +73,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
string token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiI0YjM2NmY4MDdlMjU0MzlmYmRkOTEwZDc4ZjcwYzlhMSIsInN1YiI6ImZlNmExYmUyLWM5MTEtNDM3OC05Y2MxLTVhY2Y1NjA1Y2ZjMiIsInNjb3BlIjpbImNsb3VkX2NvbnRyb2xsZXIucmVhZCIsImNsb3VkX2NvbnRyb2xsZXJfc2VydmljZV9wZXJtaXNzaW9ucy5yZWFkIiwidGVzdGdyb3VwIiwib3BlbmlkIl0sImNsaWVudF9pZCI6Im15VGVzdEFwcCIsImNpZCI6Im15VGVzdEFwcCIsImF6cCI6Im15VGVzdEFwcCIsImdyYW50X3R5cGUiOiJhdXRob3JpemF0aW9uX2NvZGUiLCJ1c2VyX2lkIjoiZmU2YTFiZTItYzkxMS00Mzc4LTljYzEtNWFjZjU2MDVjZmMyIiwib3JpZ2luIjoidWFhIiwidXNlcl9uYW1lIjoiZGF2ZSIsImVtYWlsIjoiZGF2ZSIsImF1dGhfdGltZSI6MTQ3MzYxNTU0MSwicmV2X3NpZyI6IjEwZDM1NzEyIiwiaWF0IjoxNDczNjI0MjU1LCJleHAiOjE0NzM2Njc0NTUsImlzcyI6Imh0dHBzOi8vdWFhLnN5c3RlbS50ZXN0Y2xvdWQuY29tL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbImNsb3VkX2NvbnRyb2xsZXIiLCJteVRlc3RBcHAiLCJvcGVuaWQiLCJjbG91ZF9jb250cm9sbGVyX3NlcnZpY2VfcGVybWlzc2lvbnMiXX0.Hth_SXpMAyiTf--U75r40qODlSUr60U730IW28K2VidEltW3lN3_CE7HkSjolRGr-DYuWHRvy3i_EwBfj1WTkBaXL373UzPVvNBnat9Gi-vjz07LwmBohk3baG1mmlL8IoGbQwtsmfUPhmO5C6_M4s9wKmTf9XIZPVo_w7zPJadrXfHLfx6iQob7CYpTTix2VBWya29iL7kmD1J1UDT5YRg2J9XT30iFuL6BvPQTkuGnX3ivDuUOSdxM8Z451i0VJmc0LYFBCLJ-Tz6bJ2d0wrtfsbCfuNtxjmGJevcL2jKQbEoiliYj60qNtZdT-ijGUdZjE9caxQ2nOkDkowacpw";
|
||||
string keyset = "{ 'keys':[{'kid':'foobar','alg':'SHA256withRSA','value':'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+7xH35bYBppsn54cBW+\nFlrveTe+3L4xl7ix13XK8eBcCmNOyBhNzhks6toDiRjrgw5QW76cFirVRFIVQkiZ\nsUwDyGOax3q8NOJyBFXiplIUScrx8aI0jkY/Yd6ixAc5yBSBfXThy4EF9T0xCyt4\nxWLYNXMRwe88Y+i+MEoLNXWRbhjJm76LN7rsdIxALbS0vJNWUDALWjtE6FeYX6uU\nL9msAzlCQkdnSvwMmr8Ij2O3IVMxHDJXOZinFqt9zVfXwO11o7ZmiskZnRz1/V0f\nvbUQAadkcDEUt1gk9cbrAhiipg8VWDMsC7VUXuekJZjme5f8oWTwpsgP6cTUzwSS\n6wIDAQAB\n-----END PUBLIC KEY-----','kty':'RSA','use':'sig','n':'AJPu8R9+W2AaabJ+eHAVvhZa73k3vty+MZe4sdd1yvHgXApjTsgYTc4ZLOraA4kY64MOUFu+nBYq1URSFUJImbFMA8hjmsd6vDTicgRV4qZSFEnK8fGiNI5GP2HeosQHOcgUgX104cuBBfU9MQsreMVi2DVzEcHvPGPovjBKCzV1kW4YyZu+ize67HSMQC20tLyTVlAwC1o7ROhXmF+rlC/ZrAM5QkJHZ0r8DJq/CI9jtyFTMRwyVzmYpxarfc1X18DtdaO2ZorJGZ0c9f1dH721EAGnZHAxFLdYJPXG6wIYoqYPFVgzLAu1VF7npCWY5nuX/KFk8KbID+nE1M8Ekus=','e':'AQAB'}]}";
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(keyset);
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(keyset)
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
CloudFoundryTokenKeyResolver.Resolved.Clear();
|
||||
|
@ -92,8 +93,10 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
string keyset = "{ 'keys':[{'kid':'legacy-token-key','alg':'SHA256withRSA','value':'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+7xH35bYBppsn54cBW+\nFlrveTe+3L4xl7ix13XK8eBcCmNOyBhNzhks6toDiRjrgw5QW76cFirVRFIVQkiZ\nsUwDyGOax3q8NOJyBFXiplIUScrx8aI0jkY/Yd6ixAc5yBSBfXThy4EF9T0xCyt4\nxWLYNXMRwe88Y+i+MEoLNXWRbhjJm76LN7rsdIxALbS0vJNWUDALWjtE6FeYX6uU\nL9msAzlCQkdnSvwMmr8Ij2O3IVMxHDJXOZinFqt9zVfXwO11o7ZmiskZnRz1/V0f\nvbUQAadkcDEUt1gk9cbrAhiipg8VWDMsC7VUXuekJZjme5f8oWTwpsgP6cTUzwSS\n6wIDAQAB\n-----END PUBLIC KEY-----','kty':'RSA','use':'sig','n':'AJPu8R9+W2AaabJ+eHAVvhZa73k3vty+MZe4sdd1yvHgXApjTsgYTc4ZLOraA4kY64MOUFu+nBYq1URSFUJImbFMA8hjmsd6vDTicgRV4qZSFEnK8fGiNI5GP2HeosQHOcgUgX104cuBBfU9MQsreMVi2DVzEcHvPGPovjBKCzV1kW4YyZu+ize67HSMQC20tLyTVlAwC1o7ROhXmF+rlC/ZrAM5QkJHZ0r8DJq/CI9jtyFTMRwyVzmYpxarfc1X18DtdaO2ZorJGZ0c9f1dH721EAGnZHAxFLdYJPXG6wIYoqYPFVgzLAu1VF7npCWY5nuX/KFk8KbID+nE1M8Ekus=','e':'AQAB'}]}";
|
||||
TestMessageHandler handler = new TestMessageHandler();
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
response.Content = new StringContent(keyset);
|
||||
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(keyset)
|
||||
};
|
||||
handler.Response = response;
|
||||
|
||||
CloudFoundryTokenKeyResolver.Resolved.Clear();
|
||||
|
@ -127,6 +130,4 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
Assert.NotNull(handler.LastRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Xunit;
|
||||
|
||||
|
@ -20,14 +18,11 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
public class CloudFoundryTokenValidatorTest
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void ValidateIssuer_ValidatesCorrectly()
|
||||
{
|
||||
|
||||
Assert.NotNull(CloudFoundryTokenValidator.ValidateIssuer("https://uaa.system.testcloud.com/", null, null));
|
||||
Assert.Null(CloudFoundryTokenValidator.ValidateIssuer("https://foobar.system.testcloud.com/", null, null));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class MonitorWrapper<T> : IOptionsMonitor<T>
|
||||
{
|
||||
private T _options;
|
||||
|
||||
public MonitorWrapper(T options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public T CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
}
|
||||
|
||||
public T Get(string name)
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
|
||||
public IDisposable OnChange(Action<T, string> listener)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class MyTestCloudFoundryHandler : CloudFoundryOAuthHandler
|
||||
{
|
||||
public MyTestCloudFoundryHandler(
|
||||
IOptionsMonitor<CloudFoundryOAuthOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<AuthenticationTicket> TestCreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
return await CreateTicketAsync(identity, properties, tokens);
|
||||
}
|
||||
|
||||
public async Task<OAuthTokenResponse> TestExchangeCodeAsync(string code, string redirectUri)
|
||||
{
|
||||
return await this.ExchangeCodeAsync(code, redirectUri);
|
||||
}
|
||||
|
||||
public string TestBuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
|
||||
{
|
||||
return BuildChallengeUrl(properties, redirectUri);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,9 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<!-- Next two lines needed due to https://github.com/aspnet/Hosting/issues/926 -->
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">2.0.3</RuntimeFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -28,7 +26,19 @@
|
|||
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreTestVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreTestVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class TestClock : ISystemClock
|
||||
{
|
||||
public TestClock()
|
||||
{
|
||||
UtcNow = new DateTimeOffset(2013, 6, 11, 12, 34, 56, 789, TimeSpan.Zero);
|
||||
}
|
||||
|
||||
public DateTimeOffset UtcNow { get; set; }
|
||||
|
||||
public void Add(TimeSpan timeSpan)
|
||||
{
|
||||
UtcNow = UtcNow + timeSpan;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -31,8 +29,8 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
var tempFile = Path.GetTempFileName();
|
||||
File.WriteAllText(tempFile, contents);
|
||||
return tempFile;
|
||||
|
||||
}
|
||||
|
||||
public static Stream StringToStream(string str)
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
|
@ -62,56 +60,4 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
return @"{'user_id':'13bb6841-e4d6-4a9a-876c-9ef13aa61cc7','user_name':'testssouser','email':'testssouser@testcloud.com','client_id':'44f854fd-49fe-4102-b0d1-a526dbff93d9','exp':1472803463,'scope':['openid'],'jti':'cc956120c52a431fbbb8945ac42872fd','aud':['44f854fd-49fe-4102-b0d1-a526dbff93d9','openid'],'sub':'13bb6841-e4d6-4a9a-876c-9ef13aa61cc7','iss':'https://testsso.uaa.system.testcloud.com/oauth/token','iat':1472760263,'cid':'44f854fd-49fe-4102-b0d1-a526dbff93d9','grant_type':'authorization_code','azp':'44f854fd-49fe-4102-b0d1-a526dbff93d9','auth_time':1472760254,'zid':'ef304ed0-3a5a-442e-9ad8-e4ca3ad5120e','rev_sig':'51135842','origin':'uaa','revocable':false}";
|
||||
}
|
||||
}
|
||||
|
||||
class TestMessageHandler : HttpMessageHandler
|
||||
{
|
||||
public HttpRequestMessage LastRequest { get; set; }
|
||||
public HttpResponseMessage Response { get; set; } = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
LastRequest = request;
|
||||
return Task.FromResult<HttpResponseMessage>(Response);
|
||||
}
|
||||
}
|
||||
class TestClock : ISystemClock
|
||||
{
|
||||
public TestClock()
|
||||
{
|
||||
UtcNow = new DateTimeOffset(2013, 6, 11, 12, 34, 56, 789, TimeSpan.Zero);
|
||||
}
|
||||
|
||||
public DateTimeOffset UtcNow { get; set; }
|
||||
|
||||
public void Add(TimeSpan timeSpan)
|
||||
{
|
||||
UtcNow = UtcNow + timeSpan;
|
||||
}
|
||||
}
|
||||
class MonitorWrapper<T> : IOptionsMonitor<T>
|
||||
{
|
||||
private T _options;
|
||||
|
||||
public MonitorWrapper(T options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
public T CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
}
|
||||
|
||||
public T Get(string name)
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
|
||||
public IDisposable OnChange(Action<T, string> listener)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class TestMessageHandler : HttpMessageHandler
|
||||
{
|
||||
public HttpRequestMessage LastRequest { get; set; }
|
||||
|
||||
public HttpResponseMessage Response { get; set; } = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
|
||||
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
LastRequest = request;
|
||||
return Task.FromResult<HttpResponseMessage>(Response);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class TestResponse : IHttpResponseFeature
|
||||
{
|
||||
public Stream Body
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasStarted
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public IHeaderDictionary Headers
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public string ReasonPhrase
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public int StatusCode
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
|
@ -25,12 +23,10 @@ using Microsoft.Extensions.Logging;
|
|||
using Steeltoe.Extensions.Configuration.CloudFoundry;
|
||||
using System;
|
||||
|
||||
|
||||
namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
||||
{
|
||||
public class TestServerJwtStartup
|
||||
{
|
||||
|
||||
public static CloudFoundryJwtBearerOptions CloudFoundryOptions { get; set; }
|
||||
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
|
@ -52,8 +48,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddCloudFoundryJwtBearer(Configuration);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
|
@ -83,12 +77,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
await context.ChallengeAsync();
|
||||
return;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2017 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
|
@ -29,7 +27,6 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
public class TestServerStartup
|
||||
{
|
||||
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
|
||||
public TestServerStartup(IHostingEnvironment env)
|
||||
|
@ -39,7 +36,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddCloudFoundry()
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
|
||||
Configuration = builder.Build();
|
||||
}
|
||||
|
||||
|
@ -50,16 +47,12 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme;
|
||||
|
||||
})
|
||||
.AddCookie((options) =>
|
||||
{
|
||||
options.AccessDeniedPath = new PathString("/Home/AccessDenied");
|
||||
|
||||
})
|
||||
.AddCloudFoundryOAuth(Configuration);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
|
@ -89,11 +82,7 @@ namespace Steeltoe.Security.Authentication.CloudFoundry.Test
|
|||
{
|
||||
await context.ChallengeAsync();
|
||||
return;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
// Copyright 2015 the original author or authors.
|
||||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,11 +11,9 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Security.DataProtection.Redis.Test
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">2.0.3</RuntimeFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -22,7 +23,18 @@
|
|||
<PackageReference Include="xunit" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitStudioVersion)" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче