skip to Main Content

I have what I thought was a typical application with React front end and Spring boot as the backend. I’m trying to setup security to use Azure active directory to authenticate and authorize users. Authentication works but authorization doesn’t

The UI part is simple and works, I’m using MSAL to authenticate and get the account. I can see in console log that everything is ok from that perspective. I also see the following in the token request/response:
https://login.microsoftonline.com/*{XX}*/oauth2/v2.0/token

scope: "User.Read profile openid email"
token_type: "Bearer"

The issue I’m having is in the backend, I’m getting the following error:

Failed to authorize filter invocation [GET /api/document/list] with attributes [hasAuthority('SCOPE_User.Read')] using AffirmativeBased [DecisionVoters=[org.springframework.security.web.access.expression.WebExpressionVoter@470b5213], AllowIfAllAbstainDecisions=false]
Sending JwtAuthenticationToken [Principal=org.springframework.security.oauth2.jwt.Jwt@43ebd8ff, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]] to access denied handler since access is denied

As you could see for some reason on the resource server we are not getting the scopes the user has access to (i.e. User.Read)

Spring Security setup:

@Configuration
public class SecurityConfig {
    @Bean
    SecurityFilterChain web(HttpSecurity http) throws Exception {
        http.authorizeRequests((authorize) -> authorize
                        .mvcMatchers("/**").hasAuthority("SCOPE_User.Read")      // .permitAll()
                        .anyRequest().authenticated())
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
        return http.build();
    }
}

In application.properties:

spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/{XX}/v2.0

2

Answers


  1. Chosen as BEST ANSWER

    After a lot of research I finally figured out that the request I was doing in the react code did not have the right token. The way it works is you have to first request a login token and then request a "scope" token. I had the login token but not the scope and that's why I kept getting empty granted authorities

    This site helped a lot: https://jwt.ms/. When I put the JWT in the token field it showed that there were no scopes (scp).

    This is what it should look like (screen shot from https://dev.to/czmiel24/configuring-scopes-in-azure-active-directory-part-1-3bio):

    enter image description here


  2. To be very touchy, the "backend" is a resource-server, not a client (client is React app in your case).

    I haven’t enough experience with Azure AD to be categoric, but I suspect Microsoft to not follow common OpenID practices (.well-known/openid-configuration being accessible from issuer URI and exposing JWKS_URI) , which results in Spring not resolving authorization public key correctly.

    Have you tried to set spring.security.oauth2.resourceserver.jwt.jwk-set-uri instead or in addition to spring.security.oauth2.resourceserver.jwt.issuer-uri (issuer-uri must be set with the exact value found in iss claim access-token, even trailing slash being important)?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search