omniauth-microsoft-identity2 provides a Microsoft Identity (Entra ID) OAuth2/OpenID Connect strategy for OmniAuth.
Add this line to your application's Gemfile:
gem 'omniauth-microsoft-identity2'Then run:
bundle installConfigure OmniAuth in your Rack/Rails app:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :microsoft_identity2,
ENV.fetch('MICROSOFT_CLIENT_ID'),
ENV.fetch('MICROSOFT_CLIENT_SECRET')
endCompatibility aliases are available if you want stable callback paths:
provider :microsoft_identity, ENV.fetch('MICROSOFT_CLIENT_ID'), ENV.fetch('MICROSOFT_CLIENT_SECRET')
provider :windowslive, ENV.fetch('MICROSOFT_CLIENT_ID'), ENV.fetch('MICROSOFT_CLIENT_SECRET')- Microsoft identity platform OAuth 2.0 authorization code flow
- OpenID Connect on the Microsoft identity platform
- Register callback URL (example):
https://your-app.example.com/auth/windowslive/callback
Supported options include:
tenant(default:common)scope(default:openid profile email offline_access User.Read)promptlogin_hintdomain_hintresponse_moderedirect_urinonceuid_with_tenant(default:true; yieldstid:oid_or_subwhen possible)skip_jwt(default:false; disable id_token decode inextra.id_info)
Request query parameters for supported authorize options are passed through in request phase.
- If callback fails with
message=csrf_detected, the OAuthstatevalue could not be validated. - A common local smoke-test cause is host mismatch between request and callback (for example
127.0.0.1vslocalhost), which changes cookie scope and drops the session state cookie. - Use the exact same host for request and callback URLs, and register that exact callback in Entra.
Example payload from request.env['omniauth.auth'] (realistic shape, anonymized):
{
"uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:11111111-2222-3333-4444-555555555555",
"info": {
"name": "Sample User",
"email": "sample@example.test",
"first_name": "Sample",
"last_name": "User",
"nickname": "sample@example.test",
"image": "https://graph.microsoft.com/v1.0/me/photo/$value"
},
"credentials": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
"refresh_token": "1.Aa4A...<redacted>",
"expires_at": 1772697856,
"expires": true,
"scope": "email openid profile User.Read"
},
"extra": {
"raw_info": {
"aud": "client-id",
"iss": "https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/v2.0",
"iat": 1772692424,
"nbf": 1772692424,
"exp": 1772696324,
"sid": "session-id-value",
"uti": "token-uti-value",
"ver": "2.0",
"idp": "https://sts.windows.net/tenant-id/",
"tid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"oid": "11111111-2222-3333-4444-555555555555",
"sub": "subject-value",
"name": "Sample User",
"given_name": "Sample",
"family_name": "User",
"preferred_username": "sample@example.test",
"email": "sample@example.test",
"picture": "https://graph.microsoft.com/v1.0/me/photo/$value"
},
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6I...redacted...",
"id_info": {
"aud": "client-id",
"iss": "https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/v2.0",
"iat": 1772692424,
"nbf": 1772692424,
"exp": 1772696324,
"sid": "session-id-value",
"uti": "token-uti-value",
"ver": "2.0",
"idp": "https://sts.windows.net/tenant-id/",
"tid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"oid": "11111111-2222-3333-4444-555555555555",
"sub": "subject-value",
"name": "Sample User",
"preferred_username": "sample@example.test"
}
}
}This gem uses Microsoft Identity v2 endpoints and Microsoft Graph user info endpoints:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorizehttps://login.microsoftonline.com/{tenant}/oauth2/v2.0/tokenhttps://graph.microsoft.com/oidc/userinfo- fallback:
https://graph.microsoft.com/v1.0/me
bundle install
bundle exec rakeRun Rails integration tests with an explicit Rails version:
RAILS_VERSION='~> 8.1.0' bundle install
RAILS_VERSION='~> 8.1.0' bundle exec rake test_rails_integrationtest/omniauth_microsoft_identity2_test.rb: strategy/unit behaviortest/rails_integration_test.rb: full Rack/Rails request+callback flowtest/test_helper.rb: shared test bootstrap
- Ruby:
>= 3.2(tested on3.2,3.3,3.4,4.0) omniauth-oauth2:>= 1.8,< 2.0- Rails integration lanes:
~> 7.1.0,~> 7.2.0,~> 8.0.0,~> 8.1.0
Tag releases as vX.Y.Z; GitHub Actions publishes the gem to RubyGems.
MIT