401 UNAUTHORIZED error when using IBM AppId with Spring Boot - spring-security-oauth2

I am trying to integrate a sample spring boot application with IBM AppId service. I followed the tutorial available on IBM Developer portal. Below is my configuration
application.yml
spring:
security:
oauth2:
client:
registration:
appid:
clientId: <<clientId>>
secret: <<secret>>
provider:
appid:
issuerUri: <<issuer_uri>>
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login/**", "/user", "/userInfo").authenticated()
.and()
.oauth2Login();
}
}
User is redirected to IBM login screen. After successful authentication, user is redirected back to the web application but sees below error
[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
TRACE output written to application log
2021-03-06 21:40:26.805 TRACE 2565 --- [nio-8080-exec-1] o.s.s.authentication.ProviderManager : Authenticating request with OAuth2LoginAuthenticationProvider (1/3)
2021-03-06 21:40:26.807 DEBUG 2565 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : HTTP POST https://au-syd.appid.cloud.ibm.com/oauth/v4/<<tenantId>>/token
2021-03-06 21:40:26.807 DEBUG 2565 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2021-03-06 21:40:26.808 DEBUG 2565 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[wp1MU8O9wpnCj8Opw7wlfcOVwr5nF8OUwqfDqSpow51Fw48rV8ORwrJ6w65VEgI2wrVxHhshdcOfwpo8FsKXw795OcKDw43DjzJLAsK5w7sGwqHDiVjDm3LCkW7DnQN-w7fCl8OgKSTDocKVcMOIwprCvhnCvMK1wqdYe8OMNcKJw4g0w7VKwoA8w5FdGnLDlMOqfiZnw5N9w4g7w45qw4TDgD9Nw6UDacOyasO9S8OqwpkcNgh0w4PCnMOIw5TCvMO1w5IQUy5JQ1vDtWHChMOpKcOGH1fClMKfwo3CoxDCmSLCvnM1w4TDhsKGw57CmsOcPA_ChcKwwqfCpMOiwprDtUTDs8KFw7_Drg1EEsOXUMKTwpfDvBXDjsKIw5Rpw6N1TsO3QA], redirect_uri=[http://localhost:8080/login/oauth2/code/appid]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2021-03-06 21:40:27.232 DEBUG 2565 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Response 401 UNAUTHORIZED
2021-03-06 21:40:27.235 TRACE 2565 --- [nio-8080-exec-1] o.s.s.authentication.ProviderManager : Authenticating request with OidcAuthorizationCodeAuthenticationProvider (2/3)
2021-03-06 21:40:27.235 DEBUG 2565 --- [nio-8080-exec-1] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2021-03-06 21:40:27.235 TRACE 2565 --- [nio-8080-exec-1] .s.o.c.w.OAuth2LoginAuthenticationFilter : Failed to process authentication request
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
at org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider.authenticate(OAuth2LoginAuthenticationProvider.java:113) ~[spring-security-oauth2-client-5.4.5.jar:5.4.5]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.4.5.jar:5.4.5]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:192) ~[spring-security-oauth2-client-5.4.5.jar:5.4.5]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:222) ~[spring-security-web-5.4.5.jar:5.4.5]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.4.5.jar:5.4.5]
Any suggestion to resolve this issue?

Related

Ocelot + consul + my web api (.Net 5) via HTTPS in docker

I'm trying to use Ocelot (Api gateway) + consul + my web api (.Net 5) via HTTPS in docker;
ocelot - v17.0.0
consul - latest https://hub.docker.com/_/consul
my service - ASP.NET 5 Web Api
Trust HTTPS certificate from Windows Subsystem for Linux
source: https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-5.0&tabs=visual-studio#trust-https-certificate-from-windows-subsystem-for-linux
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https --clean
Cleaning HTTPS development certificates from the machine. A prompt might get displayed to confirm the removal of some of the certificates.
HTTPS development certificates successfully removed from the machine.
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetdev.pfx -p <водкабалалайка>
The HTTPS developer certificate was generated successfully.
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https --trust
Trusting the HTTPS development certificate was requested. A confirmation prompt will be displayed if the certificate was not previously trusted. Click yes on the prompt to trust the certificate.
A valid HTTPS certificate is already present.
My docker-compose:
version: '3'
services:
license-service-web-api-01:
image: license-service-web-api
container_name: license-service-01
build:
context: .
dockerfile: Services/LicenseServiceWebApi/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:9001;http://+:9000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 9000:9000
- 9001:9001
depends_on:
- consul
gateway:
image: gateway
container_name: gateway
build:
context: .
dockerfile: ApiGateway/gateway/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:5001;http://+:5000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 5001:5001
- 5000:5000
depends_on:
- consul
consul:
image: consul
container_name: consul
command: agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0
environment:
- 'CONSUL_LOCAL_CONFIG= {"connect": {"enabled": true}}'
ports:
- 8500:8500
My configuration file "ocelot.json" (version without Consul)
{
"Routes": [
{
"SwaggerKey": "License Service",
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9000
}
],
"UpstreamHttpMethod": [ "Put", "Post", "GET" ],
"UpstreamPathTemplate": "/{everything}",
"LoadBalancerOptions": {
"Type": "LeastConnection"
},
"FileCacheOption": {
"TtlSeconds": 30
}
},
{
"DownstreamPathTemplate": "/swagger/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9000
}
],
"UpstreamPathTemplate": "/swagger/{everything}",
"FileCacheOption": {
"TtlSeconds": 666
}
}
],
"SwaggerEndPoints": [
{
"Key": "License Service",
"Config": [
{
"Name": "License Service API",
"Version": "v1",
"Service": {
"Name": "License Service",
"Path": "/swagger/v1/swagger.json"
}
}
]
}
]
}
docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------------------------------------------------------------
consul docker-entrypoint.sh agent ... Up 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 0.0.0.0:8500->8500/tcp, 8600/tcp, 8600/udp
gateway dotnet gateway.dll Up 443/tcp, 0.0.0.0:5000->5000/tcp, 0.0.0.0:5001->5001/tcp
license-service-01 dotnet LicenseServiceWebAp ... Up 443/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:9001->9001/tcp
CASE 1:
PS C:\Users\tim> curl http://localhost:9000/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:9001/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl http://localhost:5000/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:5001/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
CASE 2:
I added an https redirect in my service
app.UseHttpsRedirection();
PS C:\Users\tim> curl http://localhost:9000/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=345437c4c182
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:9001/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=345437c4c182
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl http://localhost:5000/HealthCheck/GetMachineName
curl : Unable to resolve the remote name: 'license-service-web-api-01'
docker-compose logs ..
gateway | info: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /api/{everything}
gateway | info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: No authentication needed for /HealthCheck/GetMachineName
gateway | info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: /api/{everything} route does not require user to be authorized
gateway | info: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: 307 (Temporary Redirect) status code, request uri: http://license-service-web-api-01:9000/api/HealthCheck/GetMachineName
PS C:\Users\tim> curl https://localhost:5001/HealthCheck/GetMachineName
curl : Unable to resolve the remote name: 'license-service-web-api-01'
..The logs are the same
CASE 3
I'm changed configuration file ocelot.json on https and port 9001
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9001
}
],
AND
removed line app.UseHttpsRedirection(); in my service
GET https://localhost:5001/WeatherForecast
502
225 ms
Warning: Unable to verify the first certificate
GET /WeatherForecast HTTP/1.1
User-Agent: PostmanRuntime/7.26.8
Accept: */*
Postman-Token: 6cafa9e0-e195-4082-a7d4-daac4f58dff7
Host: localhost:5001
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
HTTP/1.1 502 Bad Gateway
Date: Fri, 05 Mar 2021 14:50:01 GMT
Server: Kestrel
Content-Length: 0
gateway | info: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /api/{everything}
gateway | info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: No authentication needed for /WeatherForecast
gateway | info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: /api/{everything} route does not require user to be authorized
gateway | warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: Error Code: ConnectionToDownstreamServiceError Message: Error connecting to downstream service, exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
gateway | ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch, RemoteCertificateChainErrors
gateway | at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
gateway | at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
gateway | at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
gateway | --- End of inner exception stack trace ---
gateway | at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
gateway | at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
gateway | at Ocelot.Requester.HttpClientHttpRequester.GetResponse(HttpContext httpContext) errors found in ResponderMiddleware. Setting error response for request path:/WeatherForecast, request method: GET
I have questions, maybe someone can help me, please:
Why ocelot can't call my serive over https?
How i can https enabled for Consul inside docker - compose?
you have a ssl error last case. You may 2 options for this issue
best.option you creating your own certificate and then getting it trusted by your local or remote machine.
quick option you can add this line your ocelot.json
"DangerousAcceptAnyServerCertificateValidator": true
you should add networks tag on your docker-compose file.
like below:
version: '3'
networks:
dockerapi:
driver: bridge
services:
license-service-web-api-01:
image: license-service-web-api
container_name: license-service-01
build:
context: .
dockerfile: Services/LicenseServiceWebApi/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:9001;http://+:9000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 9000:9000
- 9001:9001
depends_on:
- consul
networks:
- dockerapi
gateway:
image: gateway
container_name: gateway
build:
context: .
dockerfile: ApiGateway/gateway/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:5001;http://+:5000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 5001:5001
- 5000:5000
depends_on:
- consul
networks:
- dockerapi

Identity Server 4 ASP.NET Quickstart 'refused connection'

I'm following the Identity Server 4 Quickstart and I'm having a weird issue even though I followed it step by step.
It says (translated from German) connection denied by target computer.
Whats weird about this is that in the API project "we"(I) said ValidateAudience = false which I thought meant that tokens aren't being validated at all.
// call api
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
var response = await apiClient.GetAsync("https://localhost:6001/identity");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
I am truly confused.The Client does get an accessToken so that's not the problem ... I hope.
Github-Repo
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
[16:15:42 Debug] IdentityServer4.Endpoints.TokenEndpoint
Start token request.
[16:15:42 Debug] IdentityServer4.Validation.ClientSecretValidator
Start client validation
[16:15:42 Debug] IdentityServer4.Validation.BasicAuthenticationSecretParser
Start parsing Basic Authentication secret
[16:15:42 Debug] IdentityServer4.Validation.PostBodySecretParser
Start parsing for secret in post body
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListParser
Parser found secret: PostBodySecretParser
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListParser
Secret id found: client
[16:15:42 Debug] IdentityServer4.Stores.ValidatingClientStore
client configuration validation for client client succeeded.
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListValidator
Secret validator success: HashedSharedSecretValidator
[16:15:42 Debug] IdentityServer4.Validation.ClientSecretValidator
Client validation success
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
Start token request validation
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
Start client credentials token request validation
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
client credentials token request validation success
[16:15:42 Information] IdentityServer4.Validation.TokenRequestValidator
Token request validation success, {"ClientId": "client", "ClientName": null, "GrantType": "client_credentials", "Scopes": "api1", "AuthorizationCode": null, "RefreshToken": null, "UserName": null, "AuthenticationContextReferenceClasses": null, "Tenant": null, "IdP": null, "Raw": {"grant_type": "client_credentials", "scope": "api1", "client_id": "client", "client_secret": "***REDACTED***"}, "$type": "TokenRequestValidationLog"}
[16:15:42 Debug] IdentityServer4.Services.DefaultClaimsService
Getting claims for access token for client: client
[16:15:42 Debug] IdentityServer4.Endpoints.TokenEndpoint
Token request success.
I think setting ValidateAudience = false will just ignore the audience claim, but still validate the other things in the token.
You can set the IncludeErrorDetails property to true and like this:
.AddJwtBearer(options =>
{
options.Audience = "payment";
options.Authority = "https://localhost:6001/";
//True if token validation errors should be returned to the caller.
options.IncludeErrorDetails = true;
When you set it to True, then you will get more details in the response header, like:
HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"
To further help you out, please post a sample access token and API configuration (Startup class)
See this article for further details
So in API/Properties/lauchsettings .... when generating the project it used a default sheme and in that sheme it sets a port of 43033 or smth

Enable CORS in ASP .NET Core 2.1 Web Api

I'm writting application in ASP .NET Core 2.1 Web API and React. I have my server on localhost:5000 and my client on localhost:3000. I wanted to send post request with axios but in browser console i see error:
OPTIONS https://localhost:5001/api/auth/login 0 ()
Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
In my Web API I try to add CORS but it doesn't seems to work. I add:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc();
...
}
And:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(options =>
options
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
...
app.UseMvc();
}
And this is my post request:
const response = await axios({
method: 'post',
url: 'http://localhost:5000/api/auth/login',
data: {
userName: this.state.controls.login.value,
password: this.state.controls.password.value
}
});
Server console after request:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/auth/login
info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
Policy execution successful.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 4.253ms 204
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 POST http://localhost:5000/api/auth/login application/json;charset=UTF-8 52
info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
Policy execution successful.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 2.1805ms 307
info: Microsoft.AspNetCore.Server.Kestrel[32]
Connection id "0HLG4CH3JIV16", Request id "0HLG4CH3JIV16:00000002": the application completed without reading the entire request body.
When I use Postman everything is fine. I receive json with token from server.
Ok, I resolve my problem. I just didn't know that I should remove "app.UseHttpsRedirection();".

Exception message: Invalid URI: The hostname could not be parsed

We have Dot.net web application windows server 2016, we have binded the url on IIS v10.
If we browse the url from web its working fine, but whenever we test it from Dynatrace Client we see error.
Exception message: Invalid URI: The hostname could not be parsed.
here is what we se on event.
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 3/12/2018 6:00:06 AM
Event time (UTC): 3/12/2018 10:00:06 AM
Event ID: 968692c222434a6396144999bc967aef
Event sequence: 566
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/4/ROOT-xxxxx
Trust level: Full
Application Virtual Path: /
Application Path: D:\path\path
Machine name: server
Process information:
Process ID: 6916
Process name: w3wp.exe
Account name: server\tappp
Exception information:
Exception type: UriFormatException
Exception message: Invalid URI: The hostname could not be parsed.
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.InvokeEndHandler(IAsyncResult ar)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
Request information:
Request URL: http://server.app.local:1110/ccccll.svc
Request path: /ccccll.svc
User host address: xx.xxx.xx.xx
User:
Is authenticated: False
Authentication Type:
Thread account name: server\app
Thread information:
Thread ID: 80
Thread account name: server\app
Is impersonating: False
Stack trace: at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.InvokeEndHandler(IAsyncResult ar)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)

IdentityServer4 along with Asp.Net 4.5 MVC Client

I am trying to authenticate an existing MVC application built with old Asp.Net (not the core version) with MVC framework.
By following IdentityServer4 and IdentityServer3 examples I have managed to get to a point where my user information is stored in LocalDB using EntityFramework and when I try to access to a restricted page in my client application I get redirected to the Login page provided by the IdentityServer4. However after successful login (based on what I see on the log) It does not redirect to the appropriate page. Address bar stays with something like http://localhost:5000/.... followed by lots of parameters and hashed values. Port 5000 is where I run my identity server and my application is hosted at port 44300 yet I couldn't manage to get back to there.
Has someone faced this kind of issue before or can someone please point me to an example which consists of IdentityServer4 along with a none Core version of Asp.Net.
Edit 1: Implementation Details
Server: IdentityServer4 implementation is almost clone of IdentityServer4 Quickstarts 6-AspNetIdentity.
Config File:
public class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
new Client
{
ClientId = "webapp",
ClientName = "Client WebApp",
AllowedGrantTypes = GrantTypes.Hybrid,
RedirectUris = { "http://localhost:44300/signin-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
AllowOfflineAccess = true
}
};
}
}
Client: Client implementation I am using is a dummy and It originates from IdentityServer3 Client examples "MVC OWIN Client (Hybrid)".
Startup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
SignInAsAuthenticationType = "Cookies",
ClientSecret = "secret",
Authority = "http://localhost:5000", //ID Server
RedirectUri = "http://localhost:44300/signin-oidc",
ClientId = "webapp",
ResponseType = "id_token code",
Scope = "openid profile",
});
}
}
Log Output: Log output after clicking secured page -> IS Login Page -> Clicking Login.
...
...
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[3]
HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Identity.Application.
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[8]
AuthenticationScheme: Identity.Application was successfully authenticated.
dbug: IdentityServer4.Hosting.EndpointRouter[0]
Request path /connect/authorize/login matched to endpoint type Authorize
dbug: IdentityServer4.Hosting.EndpointRouter[0]
Mapping found for endpoint: Authorize, creating handler: IdentityServer4.Endpoints.AuthorizeEndpoint
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize/login
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
Start authorize request (after login)
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[8]
AuthenticationScheme: Identity.Application was successfully authenticated.
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
User in authorize request: df21b123-d4b6-40ef-beed-e918bdfd56e9
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
Start authorize request protocol validation
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[8]
AuthenticationScheme: Identity.Application was successfully authenticated.
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator
info: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
ValidatedAuthorizeRequest
{
"ClientId": "webapp",
"ClientName": "Client WebApp",
"RedirectUri": "http://localhost:44300/signin-oidc",
"AllowedRedirectUris": [
"http://localhost:44300/signin-oidc"
],
"SubjectId": "df21b123-d4b6-40ef-beed-e918bdfd56e9",
"ResponseType": "code id_token",
"ResponseMode": "form_post",
"GrantType": "hybrid",
"RequestedScopes": "openid profile",
"State": "OpenIdConnect.AuthenticationProperties=m1ybV84KFOLgklhcmtb8iR6VFuDBxWSzJKpTy83w7RF3zRTwd9zHBbdSyiAHbuea2D6FM1MjCJvMbql9qjcTntyu95POoCAWGwDML0nkiaYnKPKtJxgZ7FagyvYvz87C6pYlJWmL2zbrTFkYh7IPmX-Qv9rPOfyp4uwhhbZZ731vfL1mSxuhh_p1dPVNFJJav4E8bZXyadg94EXJbqb3ecc_jQHWn1F_eiJsoVMSRdk",
"Nonce": "636268234716844341.OTFhNGE1ZTEtNTMyYy00Y2MyLWFjOGMtMDE1NjBmNDY3ZGM1NWFmNzIxMjItYTgzZC00NjJhLTk4YWMtNDExOTA0N2I4MjNl",
"SessionId": "61d148313b2a7485dd27e3110ea61fff",
"Raw": {
"client_id": "webapp",
"redirect_uri": "http://localhost:44300/signin-oidc",
"response_mode": "form_post",
"response_type": "id_token code",
"scope": "openid profile",
"state": "OpenIdConnect.AuthenticationProperties=m1ybV84KFOLgklhcmtb8iR6VFuDBxWSzJKpTy83w7RF3zRTwd9zHBbdSyiAHbuea2D6FM1MjCJvMbql9qjcTntyu95POoCAWGwDML0nkiaYnKPKtJxgZ7FagyvYvz87C6pYlJWmL2zbrTFkYh7IPmX-Qv9rPOfyp4uwhhbZZ731vfL1mSxuhh_p1dPVNFJJav4E8bZXyadg94EXJbqb3ecc_jQHWn1F_eiJsoVMSRdk",
"nonce": "636268234716844341.OTFhNGE1ZTEtNTMyYy00Y2MyLWFjOGMtMDE1NjBmNDY3ZGM1NWFmNzIxMjItYTgzZC00NjJhLTk4YWMtNDExOTA0N2I4MjNl",
"x-client-SKU": "ID_NET",
"x-client-ver": "1.0.40306.1554"
}
}
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (0ms) [Parameters=[#__get_Item_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [e].[Id], [e].[AccessFailedCount], [e].[ConcurrencyStamp], [e].[DefaultDatabaseName], [e].[DefaultDatabaseServer], [e].[Email], [e].[EmailConfirmed], [e].[HierarchyIds], [e].[LockoutEnabled], [e].[LockoutEnd], [e].[NormalizedEmail], [e].[NormalizedUserName], [e].[PasswordHash], [e].[PhoneNumber], [e].[PhoneNumberConfirmed], [e].[SecurityStamp], [e].[TwoFactorEnabled], [e].[UserName]
FROM [AspNetUsers] AS [e]
WHERE [e].[Id] = #__get_Item_0
info: IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0]
Showing consent: User has not yet consented
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 138.8585ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/consent?returnUrl=%2Fconnect%2Fauthorize%2Fconsent%3Fclient_id%3Dwebapp%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A44300%252Fsignin-oidc%26response_mode%3Dform_post%26response_type%3Did_token%2520code%26scope%3Dopenid%2520profile%26state%3DOpenIdConnect.AuthenticationProperties%253Dm1ybV84KFOLgklhcmtb8iR6VFuDBxWSzJKpTy83w7RF3zRTwd9zHBbdSyiAHbuea2D6FM1MjCJvMbql9qjcTntyu95POoCAWGwDML0nkiaYnKPKtJxgZ7FagyvYvz87C6pYlJWmL2zbrTFkYh7IPmX-Qv9rPOfyp4uwhhbZZ731vfL1mSxuhh_p1dPVNFJJav4E8bZXyadg94EXJbqb3ecc_jQHWn1F_eiJsoVMSRdk%26nonce%3D636268234716844341.OTFhNGE1ZTEtNTMyYy00Y2MyLWFjOGMtMDE1NjBmNDY3ZGM1NWFmNzIxMjItYTgzZC00NjJhLTk4YWMtNDExOTA0N2I4MjNl%26x-client-SKU%3DID_NET%26x-client-ver%3D1.0.40306.1554
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[3]
HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Identity.Application.
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[8]
AuthenticationScheme: Identity.Application was successfully authenticated.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 32.5652ms 404
Your application running an older version of .NET isn't relevant.
In this video, one of the authors of IdentityServer demonstrates how he was able to connect a WinForm application with IDS4.
The communication to the IDS4 is made through HTTP requests, your client could be anything really as long as it can handle the communication with the IDS4.
I suggest that you open fiddler and monitor the requests to view the parameters passing.
You could also use one of the quickstarts as a base to your IDS, or compare it to your setup to check what's wrong.
From your logs, it is showing that your user has not yet consented to the scopes being requested and so is attempting to navigate to a page on the Identity Server where the user can consent.
`Request starting HTTP/1.1 GET http://localhost:5000/consent?returnUrl=%2Fconnect%2Fauthorize%2Fconsent%3Fclient_id%3Dwebapp%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A44300%252Fsignin-oidc%26response_mode%3Dform_post%26response_type%3Did_token%2520code%26scope%3Dopenid%2520profile%26state%3DOpenIdConnect.AuthenticationProperties%253Dm1ybV84KFOLgklhcmtb8iR6VFuDBxWSzJKpTy83w7RF3zRTwd9zHBbdSyiAHbuea2D6FM1MjCJvMbql9qjcTntyu95POoCAWGwDML0nkiaYnKPKtJxgZ7FagyvYvz87C6pYlJWmL2zbrTFkYh7IPmX-Qv9rPOfyp4uwhhbZZ731vfL1mSxuhh_p1dPVNFJJav4E8bZXyadg94EXJbqb3ecc_jQHWn1F_eiJsoVMSRdk%26nonce%3D636268234716844341.OTFhNGE1ZTEtNTMyYy00Y2MyLWFjOGMtMDE1NjBmNDY3ZGM1NWFmNzIxMjItYTgzZC00NjJhLTk4YWMtNDExOTA0N2I4MjNl%26x-client-SKU%3DID_NET%26x-client-ver%3D1.0.40306.1554`
This step takes place before redirecting back to your calling website, so I'm guessing you haven't implemented this page on IdSvr yet,

Resources