【问题标题】:How to prevent [Authorize (Roles = "xxx")] to verify in openidconnect when using webform authentification使用web表单认证时如何防止[Authorize(Roles = "xxx")]在openid connect中进行验证
【发布时间】:2018-05-11 05:44:13
【问题描述】:

在我的登录网页中,我有一个网络表单 (Identity 2.0),您可以使用它在数据库中创建一个帐户,或者您可以使用 Azure Active Directory 对公司电子邮件进行身份验证。 (外部认证)

我已将[Authorize] 属性用于装饰UserController 中的Index() 操作。我在同一个控制器中的 List() 操作是这样装饰的:[Authorize (Roles = "Admin")]

当我使用我的 webform 登录名登录时,如果我转到 /MyController/List/,我将被重定向到 Microsoft 帐户登录页面。当转到 /MyController/Index 时,我没有被重定向。

是什么导致了这种行为?当用户使用 webform 登录时,我不想签入 Azure。我怎样才能防止这种情况发生?

这是我的 Startup.Auth.cs

    public partial class Startup
{
    private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
    private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
    private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
    private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
    private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

    public static readonly string Authority = aadInstance + tenantId;

    // This is the resource ID of the AAD Graph API.  We'll need this to request a token to call the Graph API.
    string graphResourceId = "https://graph.windows.net";


    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {

        // Configure the db context, user manager and role manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

        // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

        // Enables the application to remember the second login verification factor such as phone or email.
        // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
        // This is similar to the RememberMe option when you log in.
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

        // Pour Azure
        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = Authority,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,

            Notifications = new OpenIdConnectAuthenticationNotifications()
            {
                // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                AuthorizationCodeReceived = (context) =>
                {
                    var code = context.Code;
                    ClientCredential credential = new ClientCredential(clientId, appKey);
                    string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                    AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
                    Task<AuthenticationResult> result = authContext.AcquireTokenByAuthorizationCodeAsync(
                    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);

                    return Task.FromResult(0);
                }
            }
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);


        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");

        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");

        //app.UseGoogleAuthentication(
        //    clientId: "",
        //    clientSecret: "");
    }
}

编辑

这是控制器代码

using System.Web.Mvc;

namespace MyApp.Controllers
{

    public class AccueilController : Controller
    {
        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "Admin")]
        public ActionResult List()
        {
            return View();
        }
    }
}

我已使用 Cookie Authenticatoin(电子邮件/密码)登录。

  1. 我点击了 Index 操作,我在我的应用程序中看到了该页面的内容。
  2. 如果我点击 List() 操作,我将被重定向到 OpenIdConnect 登录页面。

【问题讨论】:

  • 使用 HttpContext.User.IsInRole("Admin") 时,它不会重定向到 AAD,而是在我使用 AAD 或 Webforms 登录时返回 false。那么[Authorize (Roles = "MyRole")] 的行为是错误吗?
  • 你能贴出两个行为不同的控制器动作的代码(减去内容)吗?
  • @Philippe 登录用户的角色是否为admin
  • @Kumar_Vikas 根本没有任何作用。

标签: c# asp.net-mvc azure webforms asp.net-identity


【解决方案1】:

webforms 用户没有管理员角色,但您的 AD 用户似乎拥有管理员角色。您可以通过快速查询AspNetUserRoles 表来验证这一点。

使用[Authorize(Roles="Admin")] 装饰操作将使其仅可供具有该角色的用户访问。未授权用户的默认行为(不管用户的身份验证状态)是将他们重定向到登录页面。

您的选择是:

  1. 继承AuthorizeAttribute 并覆盖默认行为。
  2. 如果用户已通过身份验证,则将用户从登录页面重定向到其他地方(可能是设置了正确状态代码的禁止页面)。

据我所知,如果没有像在 ASP.NET Core 中那样子类化 AuthorizeAttribute,则无法覆盖默认重定向行为。

【讨论】:

  • 有链接显示 .NET Core 行为与 .NET 4 的区别?这将帮助我了解发生了什么。谢谢。
  • @Philippe 默认行为在 .NET Core 中是相同的。但是由于所有的认证方式都使用Cookie认证,所以可以configure the application cookie
猜你喜欢
  • 2021-06-11
  • 2015-05-27
  • 1970-01-01
  • 2021-07-29
  • 2023-03-11
  • 2017-05-18
  • 2018-04-12
  • 1970-01-01
  • 2019-12-16
相关资源
最近更新 更多