关于c#:Azure B2C deny =”?”在asp.net MVC中

Azure B2C deny=“?” in asp.net MVC

我有一个要向Azure AD B2C进行身份验证的MVC应用程序。我想使用deny ="?"我的web.config中的属性。一切都很好,直到我在auth之后重定向回我的应用程序为止,在这种情况下,asp.net看不到我的用户已被授权,并且我被发送回B2C登录页面,从而导致无休止的循环。

Startup.Auth.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

// The following using statements were added for this sample
using Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using System.Threading.Tasks;
using Microsoft.Owin.Security.Notifications;
using Microsoft.IdentityModel.Protocols;
using System.Web.Mvc;
using System.Configuration;
using System.IdentityModel.Tokens;
using WebApp_OpenIDConnect_DotNet_B2C.Policies;
using System.Threading;
using System.Globalization;
using Microsoft.Owin;

namespace WebApp_OpenIDConnect_DotNet_B2C
{
    public partial class Startup
    {
        // The ACR claim is used to indicate which policy was executed
        public const string AcrClaimType ="http://schemas.microsoft.com/claims/authnclassreference";
        public const string PolicyKey ="b2cpolicy";
        public const string OIDCMetadataSuffix ="/.well-known/openid-configuration";

        // App config settings
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string aadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
        private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
        private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];

        // B2C policy identifiers
        public static string SignUpPolicyId = ConfigurationManager.AppSettings["ida:SignUpPolicyId"];
        public static string SignInPolicyId = ConfigurationManager.AppSettings["ida:SignInPolicyId"];
        public static string ProfilePolicyId = ConfigurationManager.AppSettings["ida:UserProfilePolicyId"];

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            System.Web.Mvc.UrlHelper url = new System.Web.Mvc.UrlHelper(HttpContext.Current.Request.RequestContext);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                LoginPath = new PathString(url.Action("SignIn","Account"))
            });

            OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions
            {
                // These are standard OpenID Connect parameters, with values pulled from web.config
                ClientId = clientId,
                RedirectUri = redirectUri,
                PostLogoutRedirectUri = redirectUri,
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = AuthenticationFailed,
                    RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                },
                Scope ="openid",
                ResponseType ="id_token",

                // The PolicyConfigurationManager takes care of getting the correct Azure AD authentication
                // endpoints from the OpenID Connect metadata endpoint.  It is included in the PolicyAuthHelpers folder.
                ConfigurationManager = new PolicyConfigurationManager(
                    String.Format(CultureInfo.InvariantCulture, aadInstance, tenant,"/v2.0", OIDCMetadataSuffix),
                    new string[] { SignUpPolicyId, SignInPolicyId, ProfilePolicyId }),

                // This piece is optional - it is used for displaying the user's name in the navigation bar.
                TokenValidationParameters = new TokenValidationParameters
                {  
                    NameClaimType ="name",
                },
            };

            app.UseOpenIdConnectAuthentication(options);

        }

        // This notification can be used to manipulate the OIDC request before it is sent.  Here we use it to send the correct policy.
        private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            PolicyConfigurationManager mgr = notification.Options.ConfigurationManager as PolicyConfigurationManager;
            if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
            {
                OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary[Startup.PolicyKey]);
                notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;
            }
            else
            {
                OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]);
                notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;
            }
        }

        // Used for avoiding yellow-screen-of-death
        private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            notification.HandleResponse();
            notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
            return Task.FromResult(0);
        }
    }
}

web.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  <?xml version="1.0" encoding="utf-8"?>
  <!--
    For more information on how to configure your ASP.NET application, please visit
    http://go.microsoft.com/fwlink/?LinkId=301880
    -->
  <configuration>
   
     
     
     
     
     
     
     
     
     
     
     
    </appSettings>
    <location path="account/signin">
      <system.web>
       
         
        </authorization>
      </system.web>
    </location>
    <system.web>
     
        <deny users="?" />
      </authorization>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
    <runtime>
     
        <dependentAssembly>
         
          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-4.0.20622.1351" newVersion="4.0.20622.1351" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-1.0.2.33" newVersion="1.0.2.33" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
        </dependentAssembly>
        <dependentAssembly>
         
          <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
        </dependentAssembly>
      </assemblyBinding>
    </runtime>
  </configuration>

此问题的原因:

对于DotNet的OpenIDConnect,认证和重定向是同时完成的。根据您的情况,身份验证始终比重定向慢。并且,您的应用程序中的重定向URI为" https:// localhost:44316 /",由于Request.IsAuthenticated尚未设置为true,因此再次需要身份验证。新的身份验证将覆盖旧的身份验证;因此,它只会不断地循环播放。

解决方案很简单。将您的重定向URI更改为不需要身份验证的页面。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<configuration>

 
 
 
 
 
 
 
 
 
 
 
</appSettings>
<location path="account/signin">
  <system.web>
   
     
    </authorization>
  </system.web>
</location>
<location path="Home/loginsuccess">
  <system.web>
   
     
    </authorization>
  </system.web>
</location>
<system.web>
 
    <deny users="?" />
  </authorization>
  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />
</system.web>

...

注意:此处,https://localhost:44316/Home/loginsuccess应该是一个向用户显示其身份验证状态的页面。顺便说一下,您应该将此重定向URI添加到新门户中的AD应用程序中。