Tuesday, September 2, 2025

Springboot - Authenticating Microsoft Token

 A JWT has 3 parts (Base64URL encoded, separated by dots):

<header>.<payload>.<signature>



Create a POSTMan POST request to get MS token:

POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

Send the below params in x-www.-form-urlencoded:


client_id: <id of application>
client_secret: <generated secret of that app>
score: api://<tenant-id>/.default
grant_type : client_credentials


The response would be :

{
    "token_type": "Bearer",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1QiL................."
}



Copy that access_token and get ready for actual API request:

https://<applicationurl>/<apiname>/<operationname>

For ex
https://tap/tcaservice/myapi

Send that access token as Bearer Token under Authentication Header

Here is the code for Token validation

@Component
public class MicrosoftTokenFilter extends OncePerRequestFilter {

    private final JwtDecoder jwtDecoder;

    public MicrosoftTokenFilter(@Value("${azure.ad.tenant-id}") String tenantId) {
        //String issuerUri = "https://login.microsoftonline.com/" + tenantId + "/v2.0";
        String issuerUri = "https://sts.windows.net/" + tenantId + "/";
        this.jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
    }

 @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        logger.info("Starting MicrosoftTokenFilter");
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);

            logger.info(" token = " + token);
            try {
                Jwt jwt = jwtDecoder.decode(token);

                SetupAuthentication(jwt);

            } catch (Exception e) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Microsoft token");
                return;
            }
        }

        filterChain.doFilter(request, response);
    }

    private void SetupAuthentication(Jwt jwt) {

            Map<String, Object> claims = jwt.getClaims();

            String name = "";
            String email = "";
            String orgCode = "";
            boolean isAuthUser = false;
            String environment = "TEST";
            String orgName = "";

            List<Role> roles = new ArrayList<Role>();
            for ( Map.Entry<String,Object> claim : claims.entrySet()) {

                if (claim.getKey().equals("EMAIL")) {
                    email = claim.getValue().toString();
                }
            }

            //set faked
            name = "Naas api";
            email = "vkumar@austroads.gov.au";
            orgCode = "Naas";
            isAuthUser = true;
            environment = "TEST";
            orgName = "Austroads";

            if (isAuthUser) {
                User user = new User();
                user.setFirstName("");
                user.setLastName(name);
                user.setEmail(email);
                user.setOrganisationCode(orgCode);
                user.setRoles(roles);
                user.setOrganisationName(orgName);


                Authentication authentication = createAuthentication(jwt, user, environment);
                setAuthentication(authentication);


                logger.info("Authorities set in context:" + SecurityContextHolder.getContext().getAuthentication().getAuthorities());

            }
    }

    private Authentication createAuthentication(Jwt jwt, User user, String environment) {      
        List authList = new ArrayList();  
        authList.add(new SimpleGrantedAuthority("TEST_MyAdminRole");
    JwtAuthenticationToken usertoken = new JwtAuthenticationToken(jwt, authList);
        return usertoken;      
    }

    private void setAuthentication(Authentication authentication) {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        SecurityContextHolder.setContext(context);
    }

}



No comments: