microsoft / azure-spring-boot

Spring Boot Starters for Azure services
MIT License
374 stars 460 forks source link

AADAppRoleStatelessAuthenticationFilter OR CustomFilter verification is not possible #892

Closed Gaboxondo closed 3 years ago

Gaboxondo commented 4 years ago

I am trying to develop an application with JWT security, but in this case I have two JWT filters:

In my case I have to be able to use both filters, that is, it must pass one filter OR another. If onle of the filters creates the autentication with the JWT token provided is enough to be able to make the request.

About the AADAppRoleStatelessAuthenticationFilter I have seen that it throws exception

if (StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer ")) {
            try {
                String token = authHeader.replace("Bearer ", "");
                UserPrincipal principal = this.principalManager.buildUserPrincipal(token);
                JSONArray roles = (JSONArray)Optional.ofNullable((JSONArray)principal.getClaims().get("roles")).filter((r) -> {
                    return !r.isEmpty();
                }).orElse(DEFAULT_ROLE_CLAIM);
                Authentication authentication = new PreAuthenticatedAuthenticationToken(principal, (Object)null, this.rolesToGrantedAuthorities(roles));
                authentication.setAuthenticated(true);
                log.info("Request token verification success. {}", authentication);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                cleanupRequired = true;
            } catch (BadJWTException var14) {
                String errorMessage = "Invalid JWT. Either expired or not yet valid. " + var14.getMessage();
                log.warn(errorMessage);
                throw new ServletException(errorMessage, var14);
            } catch (BadJOSEException | JOSEException | ParseException var15) {
                log.error("Failed to initialize UserPrincipal.", var15);
                throw new ServletException(var15);
            }

So if something fails it does not pass to the next filter and retruns error.

In my own filter I dont send exceptions but I only generate the Auth in case of all validations are pass

String tokenWithBearer = request.getHeader( TokenPropertiesCommon.HEADER_STRING );

        if (tokenWithBearer == null) {
            chain.doFilter( request, response );
            return;
        } else if (!tokenWithBearer.startsWith( (TokenPropertiesCommon.PREFIX) )) {
            chain.doFilter( request, response );
            return;
        }

        String token = tokenWithBearer.replace( TokenPropertiesCommon.PREFIX, "" );

        if (!validateSecret( token ) || !validateExpireAt( token )) {
            chain.doFilter( request, response );
            return;
        }

        Authentication authentication = generateAuth( token );
        SecurityContextHolder.getContext().setAuthentication( authentication );

        chain.doFilter( request, response );
    }

Actually my Customfilter do and validate more things, but this is an example In this case if this filters fails it continue with the next filters no generating Authentication.

Who can achive that with microsoft AADAppRoleStatelessAuthenticationFilter filter?

Thanks in advance

saragluna commented 4 years ago

Thanks for reaching out, we've added some check in our filter, to only check tokens issued by Azure AD. Please see #872. Could this solve your problem?

Gaboxondo commented 4 years ago

Hi @saragluna which tag did you created for this merge into master? i mean which version should I use? Thanks!

yiliuTo commented 4 years ago

Hi, this merge has not been released yet. For the mentioned update, you could try our snapshot version of 2.2.5-snapshot.

chenrujun commented 3 years ago

Closing this issue. Because it's not active for a long time. If anyone have similar issue, please create issue in new repo: https://github.com/Azure/azure-sdk-for-java/issues