oauth-2.0jwtpostmanoffice365apirsa-sha256

How to sign JWT with a RSA SHA-256 hash


I'm trying to get an access token to use office365 api through client credentials. I'm using this guide: Office 365 Rest API - Daemon week authentication

I'm sending my request using postman (see below) Postman Picture

However postman gives me this error when I send the request "AADSTS70002: Error validating credentials. AADSTS50012: Client assertion contains an invalid signature"

So I'm fairly certain I'm not signing the JWT correctly which is used for the client_assertion parameter in my request. Referring to this stack overflow question Could not retrieve app only tokens for office 365 I found that I need to sign it using a RSA SHA-256 hash. However I still couldn't get my JWT to work with any of the resources I found online on how to do this, it still would come back with the same error. Is there an online generator I can use to sign my JWT using a RSA SHA-256 hash? Or any code examples that specifically do this way of singing in C#? Thanks in advance.


Solution

  • First, you need to set up the certificates on Azure AD manifest, see blog Building Daemon or Service Apps with Office 365 Mail, Calendar, and Contacts APIs (OAuth2 client credential flow)

    About how to sign a token, here is the C# sample for your reference,

        var x509Certificate2 = new X509Certificate2(@"{FILE PATH}\office_365_app.pfx", "PASS_WORD");
    
        X509SigningCredentials signingCredentials = new X509SigningCredentials(x509Certificate2, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
    
        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
    
        var originalIssuer = "{YOUR CLIENT ID}";
    
        var issuer = originalIssuer;
    
        DateTime utcNow = DateTime.UtcNow;
    
        DateTime expired = utcNow + TimeSpan.FromHours(1);
    
        var claims = new List<Claim> {
            new Claim("aud", "https://login.microsoftonline.com/{YOUR_TENENT_ID}/oauth2/token", ClaimValueTypes.String, issuer, originalIssuer),
            new Claim("exp", "1460534173", ClaimValueTypes.DateTime, issuer, originalIssuer), 
            new Claim("jti", "{SOME GUID YOU ASSIGN}", ClaimValueTypes.String, issuer, originalIssuer),
            new Claim("nbf", "1460533573", ClaimValueTypes.String, issuer, originalIssuer),
            new Claim("sub", "{YOUR CLIENT ID}", ClaimValueTypes.String, issuer, originalIssuer)
        };
    
        ClaimsIdentity subject = new ClaimsIdentity(claims: claims);
    
        JwtSecurityToken jwtToken = tokenHandler.CreateToken(
            issuer: issuer,
            signingCredentials: signingCredentials,
            subject: subject) as JwtSecurityToken;
    
        jwtToken.Header.Remove("typ");
    
        var token = tokenHandler.WriteToken(jwtToken);
    

    You can also find the project on GitHub

    https://github.com/dream-365/OfficeDev-Samples/blob/master/samples/Office365DevQuickStart/JWT-Token