openiddict / openiddict-samples

.NET samples for OpenIddict
https://documentation.openiddict.com/
Apache License 2.0
724 stars 299 forks source link

Add an ASP.NET MVC 5.2 sample #188

Closed kevinchalet closed 2 years ago

kevinchalet commented 2 years ago

Confirm you've already contributed to this project or that you sponsor it

Describe the solution you'd like

https://github.com/openiddict/openiddict-core/issues/1380 shows that there's some interest for a legacy ASP.NET MVC 5.2 sample.

Additional context

No response

feededit commented 2 years ago

Is this space for me?

This is my first experience so I don't know the rules.

First, I will create a project that applies the code written in the linked URL.

feededit commented 2 years ago

I just uploaded MVC Client project.

here

The goal of this project is a very simple one. My worries will end when a single line appears in home/index.

home/Index.cshtml


<div class="card" >

    <h1>
        hello @User.Identity.Name !
    </h1>

</div>
feededit commented 2 years ago

If you're doing something, I'll wait. Is issue #188 still going on?

kevinchalet commented 2 years ago

I dedicated a few hours today to writing the sample. You can find it here: https://github.com/openiddict/openiddict-samples/blob/dev/samples/Mortis.

feededit commented 2 years ago

I salute you for your dedication. I was able to get Mortis because I met the best in the world.

But the ominous premonition is not wrong.

Mortis was not my plan. My plan was to bring my old site into the world of Core 6.

I have a few questions about Mortis.

Can Core6 client connect to a Mortis Host? Can Mortis use a Core6 database?

If I had to answer all my questions in one word, Is this really the only way?

Thanks again to you.

kevinchalet commented 2 years ago

I salute you for your dedication. I was able to get Mortis because I met the best in the world.

🤣

Can Core6 client connect to a Mortis Host? Can Mortis use a Core6 database?

I'm confused: I thought you wanted a MVC client sample: that's exactly what Mortis.Client is (i.e an ASP.NET MVC 5.2 app using the OIDC middleware to act as an OIDC client).

Now, you can definitely mix technologies: ASP.NET MVC 5.2 for the client (e.g Mortis.Client) and ASP.NET Core for the server (e.g Velusia.Server) and vice versa.

If it still doesn't answer your question, I'm not sure I'll be able to be much more useful.

feededit commented 2 years ago

Now it works. Its thanks to you. If I've confused you, please understand.

The second question is over. I'll ask again in a few months.

thank you.

kevinchalet commented 2 years ago

Now it works. Its thanks to you.

Great to hear that! Let me know if you have any additional question 😃

feededit commented 2 years ago

I just checked that it works. I will meet into many errors.

I had a project in progress. I needed SSO to start that project. A lot of time has been delayed. I have to spend several months on the project.

If I get an error that I can't solve, I'll ask.

feededit commented 2 years ago

On the client, User.Identity.Name works fine. Why not User.Identity.IsAuthenticated ?

Message ID: @.***>

kevinchalet commented 2 years ago

What do you mean?

image

feededit commented 2 years ago

sorry. I just checked,

I doubted Request.IsAuthenticated,

but, An error occurred because of this. @Html.AntiForgeryToken()


@if (Request.IsAuthenticated)
{
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {

        @Html.AntiForgeryToken()

Is it possible to put ID in the authentication cookie? I want to use it like this : User.Identity.ID

feededit commented 2 years ago

It's inconvenient, but I'll use it like this.


    var Users = User.Identity as System.Security.Claims.ClaimsIdentity;
            var GetUserId = Users?.FindFirst("sub")?.Value;

thank you.

kevinchalet commented 2 years ago

It's worth mentioning it's definitely not specific to OpenIddict or even the OIDC protocol: all libraries and frameworks that expose the good old IIdentity interface instead of the newer ClaimsIdentity type - like ASP.NET 4.x Web Forms, Web API 2.x or MVC 5.x - require doing a casting to access the claims.

You can make that prettier using extensions:

public static class IdentityExtensions
{
    public static string GetUserId(this IIdentity identity)
        => identity is null || !identity.IsAuthenticated ? null :
        ((ClaimsIdentity) identity).FindFirst("sub")?.Value;
}
feededit commented 2 years ago

Thanks for your help. It was what I was desperately looking for. Now I don't have to fix old sites and it saves me a lot of time. But that's not the case with .NET Framework 4.6.1 I can save more time if I can use it in .NET Framework 4.6.1. can you help me more?

kevinchalet commented 2 years ago

But that's not the case with .NET Framework 4.6.1 I can save more time if I can use it in .NET Framework 4.6.1. can you help me more?

How can I help you? 😃

feededit commented 2 years ago

You and I can't waste time on old technologies because new things come so quickly.

If it's a problem you already knew, you can tell me Don't waste your time.

kevinchalet commented 2 years ago

Unlike many developers, I don't mind working with older technologies (I even find that quite interesting!)

If you have a question, feel free to ask it.

feededit commented 2 years ago

This error occurs after the client goes to the host and logs in. What could be causing this error?


[SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys: 
kid: '[PII is hidden]', 
token: '[PII is hidden]'.]
   System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters) in C:\agent2\_work\56\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:968
   System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) in C:\agent2\_work\56\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:718
   Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.ValidateToken(String idToken, AuthenticationProperties properties, TokenValidationParameters validationParameters, JwtSecurityToken& jwt) +297
  1. In a place where everything is clean, there is no problem the first time (For example, when running this web in a browser after OS installation on a formatted hard drive)

  2. There is no error occurring even for hours while opening and viewing various pages of this web.

  3. But, after not using the web for a few hours, the web started giving errors.

  4. After this error occurs once, this error occurs even after rebooting the computer.

feededit commented 2 years ago

I'm sending you an email in case you haven't seen my request for help.

https://github.com/openiddict/openiddict-samples/issues/188#issuecomment-1058951332

Message ID: @.***>

kevinchalet commented 2 years ago

Do you use persistent signing and encryption keys/certificates? Things like AddDevelopment*Certificate() and AddEphemeral() are not suitable for production environments.

feededit commented 2 years ago

Please guide how to use persistent signing and encryption keys/certificates.

kevinchalet commented 2 years ago

Please guide how to use persistent signing and encryption keys/certificates.

https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios

How you'll store them will depend on your environment (do you use IIS, Azure App Services, containerized stuff, etc.)

feededit commented 2 years ago

In solving this error, As with the previous two questions, I prefer not to understand the principles or study them deeply. First of all, I need to fix the error. I am saving the other two questions for study.

You said that the code below is not suitable for [In production]. So I erased it like below.

          //   options.AddEphemeralEncryptionKey()
          //              .AddEphemeralSigningKey();

What should I do instead? I read the page you pointed out.

As I understand it,

  1. options.AddSigningCertificate()/options.AddEncryptionCertificate()
  2. .NET Core CertificateRequest API

I think I have to choose one of the above two. Is that right?

If I have to choose between the two, please send me the complete code for each. If you're only going to tell me one of the two, please tell me 2nd the generated and self-signed locally method.

sorry, I need to fix this error quickly.

Message ID: @.***>

kevinchalet commented 2 years ago

I prefer not to understand the principles or study them deeply.

If you don't understand what you're doing, how do you want things to work properly? 🤣

I think I have to choose one of the above two. Is that right?

No, you'll need to use both: the CertificateRequest API to generate the certificates and the options.AddSigningCertificate()/options.AddEncryptionCertificate() methods to ask OpenIddict to import your certificates and use them to protect tokens.

feededit commented 2 years ago

If you don't understand what you're doing, how do you want things to work properly?

thank you.

Actually, I've done a lot of google searches and no one can answer this error except you.

Because of this error, I am not able to start openiddick completely.

when the sun rises where you are, midnight where I am. Can I ask you a few questions in a row without sleeping tonight (It will be daytime tomorrow where you are.)? (I would like to communicate by e-mail because of my poor English.)

kevinchalet commented 2 years ago

Actually, I've done a lot of google searches and no one can answer this error except you.

https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios includes everything you need to generate your own certificates.

How you'll store them will depend on your environment. If you still need help, you'll need to provide additional details on how your app is deployed.

Can I ask you a few questions in a row without sleeping tonight

Feel free.

feededit commented 2 years ago

Please guide me how to Registering [ In production ].

  1. How to put encryption-certificate.pfx and signing-certificate.pfx on the server?
  2. What Registering code for [In production] is replacing the code below?

    // options.AddEphemeralEncryptionKey() // .AddEphemeralSigningKey();

Message ID: @.***>

kevinchalet commented 2 years ago
  1. How to put encryption-certificate.pfx and signing-certificate.pfx on the server?

You didn't say how you host your application. I can't answer without additional details.

feededit commented 2 years ago

win server 2012 iis 8.0 Central Certificates Store

Could this link help me?

kevinchalet commented 2 years ago

The CCS feature was primarily designed for SSL/TLS certificates. I'm not sure you can use it for other types of certificates.

Consider simply storing your certificates in the machine store, as explained in https://www.sonicwall.com/support/knowledge-base/how-can-i-import-certificates-into-the-ms-windows-local-machine-certificate-store/170504615105398/

After importing the certificate, make sure the application pool identity can access the private key (right click on the certificates, all tasks -> manage private keys)

feededit commented 2 years ago

I have been worried for a long time because my IIS AD CS has some problems.

I will try again and reply.

kevinchalet commented 2 years ago

Note: to configure OpenIddict to use your certificates, the best option is to use the overloads that take the certificate thumprint:

options.AddEncryptionCertificate("thumbprint of your encryption certificate");
options.AddSigningCertificate("thumbprint of your signing certificate");
feededit commented 2 years ago

It asks for a password. Couldn't find anything that could be a password.

[Subject]
  CN=Fabrikam Signing Certificate
[Issuer]
  CN=Fabrikam Signing Certificate
[Serial Number]
  1756CC981F88BB84
[Not Before]
  2022-03-09 오후 1:09:57
[Not After]
  2024-03-09 오후 1:09:57
[Thumbprint]
  A5776E60FCCE71F1BBE7A57725F2E8E460F2F89E
kevinchalet commented 2 years ago

Just leave the password field blank (unless you specified a non-empty value when calling certificate.Export(X509ContentType.Pfx, string.Empty)).

feededit commented 2 years ago

My server is very unstable and I've been avoiding changes lately. I'm also very careful with this setting.

So I ask you.

The document you provided is [signed certificate] and [CA certificate] are described.

Which one is 1, 2, or 3?

  1. signed certificate
  2. CA certificate
  3. intermediate certification authorities
kevinchalet commented 2 years ago

You only need the "Importing a signed certificate into the local machine certificate store" part.

feededit commented 2 years ago

didn't succeed..

Below is the error message.


[HttpRequestException: Response status code does not indicate success.  500(Internal Server Error).]
   System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() +121834
   Microsoft.IdentityModel.Protocols.<GetDocumentAsync>d__8.MoveNext() in C:\agent2\_work\56\s\src\Microsoft.IdentityModel.Protocols\Configuration\HttpDocumentRetriever.cs:89

[IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'.]
   Microsoft.IdentityModel.Protocols.<GetDocumentAsync>d__8.MoveNext() in C:\agent2\_work\56\s\src\Microsoft.IdentityModel.Protocols\Configuration\HttpDocumentRetriever.cs:96
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
   Microsoft.IdentityModel.Protocols.OpenIdConnect.<GetAsync>d__3.MoveNext() in C:\agent2\_work\56\s\src\Microsoft.IdentityModel.Protocols.OpenIdConnect\Configuration\OpenIdConnectConfigurationRetriever.cs:89
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
   Microsoft.IdentityModel.Protocols.<GetConfigurationAsync>d__24.MoveNext() +848

I modified as follows.

        //   options.AddEphemeralEncryptionKey()
        //             .AddEphemeralSigningKey();
        options.AddEncryptionCertificate("EAF5D3DEB86F493ACF9EF425CB7BEF838FC918CC");
        options.AddSigningCertificate("1C7198C502BA595C18DF4E8BC94C181F9434EE2C");

However, [Thumbprint] as seen in the MMC is as follows.

‎ea f5 d3 de b8 6f 49 3a cf 9e f4 25 cb 7b ef 83 8f c9 18 cc

Could the failure be due to Thumbprint? How to get the correct Thumbprint?

kevinchalet commented 2 years ago

Below is the error message.

The client logs are not very useful. Take a look at the server logs instead.

How to get the correct Thumbprint?

You can find it in the certificate details tab:

image

feededit commented 2 years ago

Application: w3wp.exe
CoreCLR Version: 6.0.121.56705
.NET Version: 6.0.1
Description: The process was terminated due to an unhandled exception.
Exception Info: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The specified file could not be found.
   at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider, CngKeyOpenOptions openOptions)
   at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider)
   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder.AddSigningKey(SecurityKey key)
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder.AddSigningCertificate(X509Certificate2 certificate)
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder.AddSigningCertificate(String thumbprint)
   at Program.<>c.<<Main>$>b__0_5(OpenIddictServerBuilder options) in C:\Projects\WebFarm\EutHost\EutHost\EutHost\Program.cs:line 89
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerExtensions.AddServer(OpenIddictBuilder builder, Action`1 configuration)
   at Program.<Main>$(String[] args) in C:\Projects\WebFarm\EutHost\EutHost\EutHost\Program.cs:line 69

They go into [iis 8.0 Central Certificates Store] even if I put them in MMC. I suspect that [File Naming Conventions] may be the cause of the error.

kevinchalet commented 2 years ago

This error indicates that the Windows CNG API was unable to access the private key associated with the certificate. Are you sure you checked "import the private key" checkbox when importing your certificate? Did you grant the application pool identity the right to access your private key?

feededit commented 2 years ago

Did you grant the application pool identity the right to access your private key?

I have absolutely no knowledge of [grant the application pool identity ]. Instructions on how to set [application pool identity] are not provided by you or Google search. Is the cause of this difficulty because my server is 2012? Are there any server versions that do not require these settings?

kevinchalet commented 2 years ago

Instructions on how to set [application pool identity] are not provided by you...

I did already mention how to do that earlier in this thread 🤷🏻

After importing the certificate, make sure the application pool identity can access the private key (right click on the certificates, all tasks -> manage private keys)


... or Google search.

Hum: https://lmgtfy.app/?q=application+pool+identity+certificate+permissions

Here's a detailed guide on how to do it: https://serverfault.com/a/132791

Are there any server versions that do not require these settings?

No.

kevinchalet commented 2 years ago

I opened https://github.com/openiddict/openiddict-documentation/issues/40 to track adding a how-to guide to help folks deploy apps that use OpenIddict (even though deploying certs is not really specific to OpenIddict).

kevinchalet commented 2 years ago

Haha, don't be, we're all here to learn 😄 (you just need to read my replies more carefully to avoid asking questions that were already answered)