Azure-Samples / azure-spring-boot-samples

Spring Cloud Azure Samples
MIT License
162 stars 228 forks source link

[FEATURE REQ] Update sample of Azure AD B2C resource-server #551

Open chenrujun opened 1 year ago

chenrujun commented 1 year ago

Context

Customer has more asks for Azure AD B2C resource-server: https://github.com/MicrosoftDocs/azure-dev-docs/issues/937#issuecomment-1303066933

1) Should explain how to get the access token in Postman. I remember struggling a lot with this one. 2) The sample uses the deprecated WebSecurityConfigurerAdapter. Should usse org.springframework.security.web.SecurityFilterChain 3) Would be nice to have a sample covering Groups (admins, users, special admins). But from what I can see there is no support for user groups in B2C.

Goal

remybd commented 1 year ago

Hello

Do you have any news or at least any documentation on this topic for azure spring cloud 5 ? At least for the use of SecurityFilterChain.

I'm not finding this documentation or example anywhere on how to use azure spring cloud 5 to setup authentication with azure ad.

Thanks a lot in advance

chenrujun commented 1 year ago

@remybd Thanks for reaching out.

@moarychan is working on this. Hi, @moarychan what's the status of Azure AD B2C related doc about Spring Coud Azure 5?

moarychan commented 1 year ago

Hi @chenrujun and @remybd , the use of SecurityFilterChain will be ready soon, the PR is in review, then you can check this doc https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-security-support#spring-security-with-azure-active-directory-b2c

remybd commented 1 year ago

Hello

I'm back after a few month on this topic. It seems the documentation is updated but I'm still not able to make it works.

I follow this exemple https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-security-support?tabs=SpringCloudAzure5x#usage-3-accessing-a-resource-server

First difference with the documentation, it seems I need to use enabled: true and a user-flows, else the url for the azure ad b2c is not good (missing the flow inside).

Problem, when I'm setting up a user flow, the preconfiguration switch automatically to a client flow (trying to log me with redirection).

I probably miss something in the documentation. spring: cloud: azure: active-directory: b2c: enabled: true base-uri: "https://ad.dev.mydpmain" profile: tenant-id: "one uuid" credential: client-id: "one uuid" user-flows: sign-up-or-sign-in: B2C_1_Datx_SignIn

Do you kow how to force the flow to be a resource server ? like for application type for normal azure ad ? https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-security-support?tabs=SpringCloudAzure5x#application-type

I would still be interested by the running example. Do you now if they are plan in the coming weeks ?

Thanks and sorry to restart this thread

moarychan commented 1 year ago

Hi @remybd , thanks for your update! The enabled: true is required; the base URI should be like this https://<your-org-name>.b2clogin.com/<your-org-name>.onmicrosoft.com; a login-in user flow is required, the doc will be updated soon.

Please check this section Samples for Spring Boot 3 to work with Spring boot 3, and the resource server sample is aad-b2c-resource-server, please try this sample.

remybd commented 1 year ago

Hello

Thanks for the fast reply. The example is working for spring 2.7 and azure-cloud 4. But there is not example or working code for spring 3 and azure 5. no ?

I have tried to upgrade the pom and to use the new spring security from the documentation. But then I encounter the same problem : the backend is trying to login me as a client and not as a server. https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-security-support?tabs=SpringCloudAzure5x#usage-3-accessing-a-resource-server

Are you able to make an example work on your side with spring 3 and azure 5 ? for resource server ?

I will try to deep dive in the code to understand better what I'm missing

remybd commented 1 year ago

My understanding looking at the code is that AadB2cOAuth2ClientConfiguration is automatically setup when there is a user flow setup. this check is done with @Conditional(AadB2cConditions.ClientRegistrationCondition.class)

In this class, there is no possibility to do differentiate between a client flow and a resource server flow. So the client flow is configure and take the advantage compare to the resource server configuration.

@Override
        public ConditionOutcome getMatchOutcome(final ConditionContext context,
                                                final AnnotatedTypeMetadata metadata) {
            ConditionMessage.Builder message = ConditionMessage.forCondition(
                "AAD B2C OAuth 2.0 Clients Configured Condition");
            AadB2cProperties aadb2CProperties = getAadB2cProperties(context);
            if (aadb2CProperties == null) {
                return ConditionOutcome.noMatch(message.notAvailable("aad b2c properties"));
            }

            if (CollectionUtils.isEmpty(aadb2CProperties.getUserFlows())
                && CollectionUtils.isEmpty(aadb2CProperties.getAuthorizationClients())) {
                return ConditionOutcome.noMatch(message.didNotFind("registered clients")
                                                       .items(KEY_OF_USER_FLOWS, "authorization-clients"));
            }

            StringBuilder details = new StringBuilder();
            if (!CollectionUtils.isEmpty(aadb2CProperties.getUserFlows())) {
                details.append(getConditionResult(KEY_OF_USER_FLOWS, aadb2CProperties.getUserFlows()));
            }
            if (!CollectionUtils.isEmpty(aadb2CProperties.getAuthorizationClients())) {
                details.append(getConditionResult("authorization-clients",
                    aadb2CProperties.getAuthorizationClients()));
            }
            return ConditionOutcome.match(message.foundExactly(details.toString()));
        }

so either we have a user flow configure and the Client Configuration is activated or we don't have a user flow, but in this case the url to contact the ad b2c will be wrong with null inside because it needs the user flow.

I'm opening a bug on the main repository. Thanks for your help

On the aad library, there is another condition

if (applicationType == null || applicationType == RESOURCE_SERVER) {
            return ConditionOutcome.noMatch(
                message.because("Resource server does not need client registration."));
        }