openiddict / openiddict-core

Flexible and versatile OAuth 2.0/OpenID Connect stack for .NET
https://openiddict.com/
Apache License 2.0
4.41k stars 515 forks source link

signin-oidc not handled? #556

Closed Trojaner closed 6 years ago

Trojaner commented 6 years ago

For some reason the redirect to "/sigin-oidc" gets handled by the Angular SPA fallback (app.UseSPA(...)) (Of course Angular reports that the given route does not exist)

I'm trying to add signin with implicit flow but because of this issue I can't get it to work.

I am using the AspNetCoreSpa template with minor modifications.

Edit:

var descriptor = new OpenIddictApplicationDescriptor
{
    ClientId = "xxxx",
    DisplayName = "xxxx",
    PostLogoutRedirectUris = { new Uri($"{host}signout-oidc") },
    RedirectUris = { new Uri($"{host}signin-oidc") },
    Permissions =
    {
        OpenIddictConstants.Permissions.Endpoints.Authorization,
        OpenIddictConstants.Permissions.Endpoints.Token,
        OpenIddictConstants.Permissions.GrantTypes.Implicit,
        OpenIddictConstants.Permissions.GrantTypes.Password,
        OpenIddictConstants.Permissions.GrantTypes.RefreshToken
     }
};

I don't know much about OpenID Connect or oAuth, but doesn't openiddict handle /signin-oidc?

kevinchalet commented 6 years ago

I don't know much about OpenID Connect or oAuth, but doesn't openiddict handle /signin-oidc?

Nope. The callback route is purely a client thing, not a server concern. The value /signin-oidc is usually used by the MSFT OIDC client middleware. Do you use it?

Trojaner commented 6 years ago

Oh, ok, seems like I misunderstood how it works there. I'm using angular-oauth2-oidc on client. I will handle the request on client in that case.

Another issue I have: After a successful authentication on an external provider, when SignIn() gets called here, the User does not really sign in. HttpContext.User is null on next request. Any idea why this happens? (No exceptions in console)

Edit Nevermind: There is an error in console: Bearer was not authenticated. Failure message: Authentication failed because the access token was invalid.

Thanks for your help!

kevinchalet commented 6 years ago

HttpContext.User is null on next request. Any idea why this happens?

That's a bit vague. Care to explain? The line you mentioned only returns an OAuth2 response by redirecting the user agent to the callback URL of the client application (it doesn't create cookies if that's your question).

Trojaner commented 6 years ago

I edited the message (I get Bearer was not authenticated. Failure message: Authentication failed because the access token was invalid. in console)

Well after the response the client gets redirected, I expected it to log in but apparently it fails..

395 seems similar, I will have a look at it.

Trojaner commented 6 years ago

So I get an access token from the server, however, for some reason the database does not contain any tokens?

      The authorization response was successfully returned to 'http://localhost:5000/' using the fragment response mode: {
        "resource": "resource_server",
        "scope": "openid email profile offline_access roles",
        "token_type": "Bearer",
        "access_token": "[removed for security reasons]",
        "expires_in": 1800,
        "id_token": "[removed for security reasons]",
        "state": "wm4VMEMW9wm9nH2inEbGcQutahrOlYN96qixcdDo"
      }.

The client also sends the said access_token but I get the error posted earlier If needed I can move this to a new issue.

kevinchalet commented 6 years ago

Change the default log level to Trace and post your entire log messages, please.

Trojaner commented 6 years ago

log-20180213.txt

kevinchalet commented 6 years ago

Change the default log level to Trace

Trojaner commented 6 years ago

Sorry, I forgot to change Serilog's min log level too.

Client sending access token: image

app-20180213.txt

2018-02-13T17:01:52.0139337+03:00 0HLBIT8K4Q79S:00000007 [VRB] A new access token was successfully generated using the specified data format: "CfDJ8DmXlM-7JedFm0lHWEPm3xDqFRpPuQduVfj_EJG4UFU9YFHa4rbQsNcWfWcpkzKAENFxvp5mAT5lfhC2Dzh2QJPwWVcSXF5NPMbKe6rN-yJI6EfRPKVtie9YI4hDvBoBizHEvE9BvjgYqnM0WxdUnbVTR8aWMQim4uLDUKDLGB9FM5f0_39EGARZCDfPfdfCiqcy9upZDJSBjrN_WNqmBBpkg49aGGctpZ52ic7V2_O7UpYkZ74L00697-30A_hiktKhcV31KGoEX_rvSnrFZCZ0ftLxoRaHPNS3DgfJ0UTdoQ_u7QVNzRreLOK3-HBP3o5Zv9XPzrHot-1mUTWR4FOIsVq8JLS6re1lcKmKqg3I9gUS2UY4hJukt-id2dlmZZcrhDeBIWt0XHpwdiBYG7qiaESfyfZ560sfamgGDwhVzstSgOr_h7SyBdT5sWI_DkAyEarBptR7DhwAYLKmEsZsIAD0Kk4HAuYQKdf6FhidF30mg9t2B9U9IbrxDgZ-Zih7EtpmV4tKzevF4c3lNe625MCSW7uVI7kAqjNp0qto5sp-9Mmk1q3M138F_Hw--on9OHxd25dFmYxoQ-7JD0FXt63TBEC5YUxO2vOn6LyEt4Jp6u_aBtgTioB0d5YllxiWrTVpR_vXTqGHC7OxbNA" [...] (7d45e235)

But why do I still get this?

2018-02-13T17:01:54.8037124+03:00 0HLBIT8K4Q79U:00000003 [DBG] Authentication was skipped because no bearer token was received. (9de85986)

and

2018-02-13T17:02:15.2543235+03:00 0HLBIT8K4Q79L:00000004 [INF] "Bearer" was not authenticated. Failure message: "Authentication failed because the access token was invalid." (48071232)

kevinchalet commented 6 years ago

Are you 100% sure the access token is not stripped?

When validating the token, you should have a trace similar to this one indicating that ASP.NET Core Data Protection tried to decrypt it:

App> trce: Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector[5]
App>       Performing unprotect operation to key {696a89f8-7f6b-4afd-9af7-e4ff7d6c616f} with purposes ('[path of your project]', 'OpenIdConnectServerHandler', 'AccessTokenFormat', 'ASOS').
App> info: AspNet.Security.OAuth.Validation.OAuthValidationHandler[8]
App>       AuthenticationScheme: Bearer was successfully authenticated.

The fact you don't have this message makes me think the token is malformed and can't be base64url-decoded by ASP.NET Core.

Trojaner commented 6 years ago

Finally I was able to figure out why it does not work.

I was using a HttpInterceptor from angular to set Authentication header (as you can see above on the image). But since I was using the older and outdated Http class for API requests, the HttpInterceptor didn't work, so the authentication header didn't get set. Migrating to the newer HttpClient (which supports the interceptor) fixed the issue (well some requests were already using the HttpClient and that confused me a lot on debugging)

Thank you for your time! And thanks for providing this great library!