ASP.NET Razor(v3)网站集成微软账户OAuth登录失败求助
Hey there, let's break down what's tripping up your Microsoft Account OAuth/OpenID integration in your Razor site. I notice you've mixed two approaches—using the built-in OAuthWebSecurity.RegisterMicrosoftClient and rolling a custom MyOAuthClient—and that's probably part of the issue. Let's fix this step by step.
First: Ditch the Custom Client (Unless You Really Need It)
Your MyOAuthClient uses placeholder endpoints and a generic OAuth setup that doesn't match Microsoft's actual OAuth/OpenID Connect flow. The built-in RegisterMicrosoftClient is purpose-built to handle Microsoft's authentication correctly, so we'll focus on getting that working first.
Step 1: Fix the Built-In Microsoft Client Registration
Make sure your auth registration is clean and uses the correct method. Update your AuthConfig class like this:
using Microsoft.AspNet.WebPages.OAuth; public static class AuthConfig { public static void RegisterAuth() { // Remove the custom MyOAuthClient code—we don't need it for basic Microsoft login OAuthWebSecurity.RegisterMicrosoftClient( clientId: "YOUR_ACTUAL_CLIENT_ID", clientSecret: "YOUR_ACTUAL_CLIENT_SECRET"); } }
Also, double-check that you have the Microsoft.AspNet.WebPages.OAuth NuGet package installed—it's required for OAuthWebSecurity to work.
Step 2: Verify Your Azure AD App Configuration
This is the #1 culprit for login failures. Since Microsoft Account uses Azure AD behind the scenes, make sure your app is set up correctly:
- Redirect URI: Must match exactly what's in your Razor site. For most Razor projects, this is
https://your-domain/Account/ExternalLoginCallback(adjust the domain/path if your callback is elsewhere). - Client Secret: Ensure it's the correct, non-expired secret from your Azure AD app (avoid copy-pasting extra spaces!).
- Permissions: Add the delegated
User.Readpermission (it's required for basic user profile access during login).
Step 3: Check Your Login Callback Implementation
Make sure you have a properly implemented ExternalLoginCallback method in your Account.cshtml.cs (or equivalent page):
public ActionResult ExternalLoginCallback(string returnUrl) { // Verify the authentication response from Microsoft var result = OAuthWebSecurity.VerifyAuthentication( Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl })); if (!result.IsSuccessful) { // Add logging here to capture error details (e.g., result.ErrorMessage) return RedirectToAction("Login"); } // Sign the user in if authentication succeeded OAuthWebSecurity.Login( result.Provider, result.ProviderUserId, createPersistentCookie: false); return RedirectToLocal(returnUrl); } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index", "Home"); } }
Step 4: Debug Like a Pro
If it's still failing, enable detailed logging to see exactly where things go wrong:
Add this to your web.config to generate a DotNetOpenAuth log file (it powers OAuthWebSecurity under the hood):
<configuration> <system.diagnostics> <trace autoflush="true" /> <sources> <source name="DotNetOpenAuth" switchName="DotNetOpenAuth" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="file" type="System.Diagnostics.TextWriterTraceListener" initializeData="DotNetOpenAuth.log" /> </listeners> </source> </sources> <switches> <add name="DotNetOpenAuth" value="Verbose" /> </switches> </system.diagnostics> </configuration>
You can also check your browser's network tab when clicking the login button—look for 400/401 errors from Microsoft's endpoints, which will tell you if it's a bad client secret, wrong redirect URI, or missing permissions.
Why Your Custom Client Wasn't Working
Microsoft uses OpenID Connect (built on OAuth 2.0) with specific endpoints that your custom client didn't use:
- Authorization endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize - Token endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/token - User info endpoint:
https://graph.microsoft.com/v1.0/me
But again, the built-in client handles all this for you, so you don't need to reinvent the wheel here.
内容的提问来源于stack exchange,提问作者PatsonLeaner

