无法在MVC应用程序中的自定义授权属性中访问身份声明

时间:2016-07-21 14:21:13

标签: identityserver3 authorize-attribute

我正在尝试将POC从现有MVC 4应用程序中的表单身份验证切换到基于声明的应用程序,但无法使自定义授权属性工作 - 由于总cookie大小而导致无限重定向循环以已知的“错误请求”问题结束... 原因 - 尽管我在SecurityTokenValidated处理程序中看到成功创建了具有预期声明集合的标识,但我在调试中看到它在属性上下文中没有经过身份验证的身份(以及正确的声明集合)。

因此,在OIDC中间件处理之后,它似乎在某种程度上丢失,并且在属性上下文中不可用,因此我无法进一步检查“角色”声明。

也许我错过了什么?

我的OWIN初创公司:

AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub";
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
        });

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "oidc",
            //AuthenticationMode = AuthenticationMode.Active, // ? https://github.com/IdentityServer/IdentityServer3/issues/1963
            Authority = OAuthServerUrl,
            ClientId = "my_app",
            RedirectUri = MyAppUrl,
            ResponseType = "id_token token", //notice, if response type 'token' is requested, IdentityServer stops including the claims in the identity token, though we could set alwaysInclude=true for some scope claims (ex. for role)
            Scope = "openid profile roles",
            SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
            PostLogoutRedirectUri = MyAppUrl,
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = n =>
                {
                    var id = n.AuthenticationTicket.Identity;
                    //n.OwinContext.Authentication.SignIn(id);
                    //tried SignIn() explicitly, and even setting HttpContext.Current.User and Thread.CurrentPrincipal to n.AuthenticationTicket.Identity, but without luck 
                    return Task.FromResult(0);
                },
                RedirectToIdentityProvider = async n =>
                {
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    {
                        var result =
                            await n.OwinContext.Authentication.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationType);
                        var idToken = result?.Identity.Claims.GetValue("id_token");
                        if (idToken != null)
                        {
                            n.ProtocolMessage.IdTokenHint = idToken;
                        }
                    }

                    await Task.FromResult(0);
                }
            }
        });

我的自定义属性继承自System.Web.Mvc.AuthorizeAttribute:

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        //var owinContext = HttpContext.Current.GetOwinContext();
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // 403 we know who you are, but you haven't been granted access
            filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            // 401 who are you? go login and then try again
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}

其中filterContext.HttpContext.User.Identity(也尝试过HttpContext.Current.User和Thread.CurrentPrincipal)具有来自LOCAL AUTHORITY颁发者的单一“名称”声明的声明集合(默认值为?)。 我还修改了Web.config来禁用表单auth:

<authentication mode="None">
...
<membership>
        <providers>
            <clear />
            <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="999" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="3" passwordStrengthRegularExpression="" applicationName="Audit" />
            <!--<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="999" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="3" passwordStrengthRegularExpression="" applicationName="Audit" />-->
        </providers>
    </membership>
    <profile>
        <providers>
            <clear />
            <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="Audit" />
            <!--<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="Audit" />-->
        </providers>
    </profile>
    <roleManager enabled="true">
    <roleManager enabled="false">
        <providers>
            <clear />
            <add connectionStringName="ApplicationServices" applicationName="Audit" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <add applicationName="Audit" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <!--<add connectionStringName="ApplicationServices" applicationName="Audit" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />-->
            <!--<add applicationName="MyApp" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />-->
        </providers>
    </roleManager>
...
<handlers>
<remove name="FormsAuthentication" />
<remove name="RoleManager" />

更新1:我已经将应用程序从MVC 4迁移到最新的MVC 5,希望它是与MVC 4相关的问题,但不幸的是,没有区别。显然,我的客户端应用程序/配置有问题。

0 个答案:

没有答案