mrochon / b2csamples

MIT License
132 stars 41 forks source link

Rest Functions API Client Cert Authentification #4

Closed bauera-hk closed 3 years ago

bauera-hk commented 4 years ago

Hi,

this project helped me a lot to understand B2C and try it out, thanks for that.

But there is one Problem. When i try to create the Tenant i get the error Message:

Client certificate specified for 'REST-CreateTenant' is invalid. Check that the certificate is correct, contains a private key and that access has been granted by the resource.

In the RestFunctions API it is failing at

var certHeader = context.Request.Headers["X-ARR-ClientCert"];`
if (!String.IsNullOrEmpty(certHeader))

My policy looks like

          <Metadata>
            <Item Key="ServiceUrl">https://myrestfunctions.azurewebsites.net/tenant</Item>
            <Item Key="AuthenticationType">ClientCertificate</Item>
            <Item Key="SendClaimsIn">Body</Item>     
          </Metadata>
          <CryptographicKeys>
            <Key Id="ClientCertificate" StorageReferenceId="B2C_1A_RESTClientCert" />
          </CryptographicKeys>

i also tried with AllowInsecureAuthInProduction true

and my policy key:

{
    "metadata": {
        "updatedUtc": "4/2/2020 11:23:32 AM",
        "tenantID": "tenant.onmicrosoft.com",
        "storageKeyId": "B2C_1A_RESTClientCert"
    },
    "keys": [
        {
            "kid": "920...C26",
            "exp": 1617362486,
            "nbf": 1585825886,
            "key_ops": [
                "sign"
            ],
            "x5c": [
                "MIIDFjCC...tLOb7s="
            ],
            "x5t": "kgh...iLCY",
            "kty": "RSA",
            "e": "AQAB",
            "n": "60s5kVcmN...mN2TRCQ"
        }
    ]
}

I used the following powershell script to generate the certificate:

New-SelfSignedCertificate `
    -KeyExportPolicy Exportable `
    -Subject "CN=herrenknechtb2ctest" `
    -KeyAlgorithm RSA `
    -KeyLength 2048 `
    -KeyUsage "DigitalSignature","KeyEncipherment" `
    -NotAfter (Get-Date).AddMonths(12) `
    -CertStoreLocation "Cert:\CurrentUser\My"`
    -HashAlgorithm sha1

Would be great if you give me some hints where to look at.

Regards, Andreas

mrochon commented 4 years ago

Hi Andreas, I assume you the first message (Client certificate is not valid...) in the B2C journey UI. Is that correct? That would indicate that journey has problems using your cert. Did you upload the pfx (private key) to B2C? To use AllowInsecureAuth attribute, change AuthenticationType from ClientCertificate to None & tell your Azure web service to NOT use a certificate authorization. Hope this helps, Marius

bauera-hk commented 4 years ago

i managed to solve the first problem. it was a wrong setting in the Azure App Service.

Via Rest Function App Service -> Configuration -> General Settings -> Incoming client certificates i selected "Require incoming certificate ON" and now the certificate authentication seems to work fine.

Now i get a new error although i checked your newly done documentation but i couldn't solve it.

I can create new Tenants which are created as Groups with owners in the Azure AD B2C but as soon as i try to signin i get the error

An error response was returned by the OAuth2 server, but it could not be parsed. 
at B2CMultiTenant.Startup.<>c.<<OptionsFor>b__5_1>d.MoveNext() in \B2CMultiTenant\B2CMultiTenant\Startup.cs:line 139 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RunAuthorizationCodeReceivedEventAsync(OpenIdConnectMessage authorizationResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt) at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()

do you maybe have a hint for me?

mrochon commented 4 years ago

The error stack includes this reference: RunAuthorizationCodeReceivedEventAsync, which may indicate that your web app is unable to redeem the authorization code. Is the app secret setup in B2C and provided to the app? (I do it through web app's configuration setting. In fact you need two such setting, which do not appear in my appsettings.json - they are in a secret config): AzureAD:ClientSecret (key created for the app in B2C) Invitation:SigningKey - use IEF Keys tab to create this secret and provide it to the web app. It is a symmetric key used to sign the invitations. BTW, I am currently working on creating a scripted setup for these apps.

bauera-hk commented 4 years ago

ok got it working now.

i double checked the secret but i think the real problem was i missed to replace the B2C Authority URL in the TokenService.cs Line 33 and the Scope in RESTService.cs line 20