【问题标题】:Thinktecture BasicAuthenticationSecurityTokenHandler returning StatusCode 500, Internal Server ErrorThinktecture BasicAuthenticationSecurityTokenHandler 返回 StatusCode 500,内部服务器错误
【发布时间】:2015-10-27 09:24:24
【问题描述】:

我最近从较旧的 Thinktecture IdentityModel 升级到支持 Web API 2 的最新 IdentityModel。

当我使用 System.Web.Mvc v5.2.2.0 时,以下代码适用于以前的 nuget 包(以及托管它的较小 webapi 版本),尽管它到达 ValidateToken 函数的末尾,但收到错误调用客户端{StatusCode: 500, ReasonPhrase: 'Internal Server Error'

public class BasicAuthSecurityTokenHandlerWithClaimsOutput : BasicAuthenticationSecurityTokenHandler
{
    public BasicAuthSecurityTokenHandlerWithClaimsOutput(ValidateNameWithClaims validateNameGetClaims)
        : base()
    {
        if (validateNameGetClaims == null)
        {
            throw new ArgumentNullException("ValidateNameGetClaims");
        }

        this.validateNameGetClaims = validateNameGetClaims;
    }

    protected readonly ValidateNameWithClaims validateNameGetClaims;

    public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
    {
        if (token == null)
        {
            throw new ArgumentNullException("token");
        }

        if (base.Configuration == null)
        {
            throw new InvalidOperationException("No Configuration set");
        }

        UserNameSecurityToken unToken = token as UserNameSecurityToken;
        if (unToken == null)
        {
            throw new ArgumentException("SecurityToken is not a UserNameSecurityToken");
        }

        Claim[] lookedUpClaims = null;

        try
        {
            if (this.validateNameGetClaims(unToken.UserName, unToken.Password, out lookedUpClaims) == false)
            {
                throw new SecurityTokenValidationException(unToken.UserName);
            }
        }
        catch (Exception e)
        {
            // log the exception
            throw new SecurityTokenValidationException(unToken.UserName);
        }

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, unToken.UserName),
            new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password),
            AuthenticationInstantClaim.Now
        };

        if(lookedUpClaims != null && lookedUpClaims.Length > 0)
            claims.AddRange(lookedUpClaims);

        if (RetainPassword)
        {
            claims.Add(new Claim("password", unToken.Password));
        }

        var identity = new ClaimsIdentity(claims, "Basic");

        if (Configuration.SaveBootstrapContext)
        {
            if (this.RetainPassword)
            {
                identity.BootstrapContext = new BootstrapContext(unToken, this);
            }
            else
            {
                var bootstrapToken = new UserNameSecurityToken(unToken.UserName, null);
                identity.BootstrapContext = new BootstrapContext(bootstrapToken, this);
            }
        }

        return new List<ClaimsIdentity> { identity }.AsReadOnly();
    }
}

我要返回的声明是:

[0] = {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: user@username.com}
[1] {http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod: http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password}
[2] {http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant: 2015-01-27T00:50:20.603Z}
[3] {fuid: 6}
[4] {fustate: FL}

我的配置:

public static class BasicAuthHandlerExtensionWithClaimsOutput
{
    public static void AddBasicAuthenticationWithClaimsOutput(
        this AuthenticationConfiguration configuration,
        ValidateNameWithClaims validationDelegate,
        string realm = "localhost", bool retainPassword = false)
    {
        var handler = new BasicAuthSecurityTokenHandlerWithClaimsOutput(validationDelegate)
        {
            RetainPassword = retainPassword
        };

        configuration.AddMapping(new AuthenticationOptionMapping
        {
            TokenHandler = new SecurityTokenHandlerCollection { handler },
            Options = AuthenticationOptions.ForAuthorizationHeader(scheme: "Basic"),
            Scheme = AuthenticationScheme.SchemeAndRealm("Basic", realm)
        });
    }
}

var authConfig = new AuthenticationConfiguration
{
    EnableSessionToken = true,
    SendWwwAuthenticateResponseHeaders = true,
    RequireSsl = false,

    SessionToken = new SessionTokenConfiguration
    {
        Audience = "http://audience.com,
        IssuerName = "http://issuer.com",
        EndpointAddress = appSettings.TokenEndPoint,
        SigningKey = appSettings.StsSigningKey,
        DefaultTokenLifetime = new TimeSpan(1, 0, 0)
    }
};

var userCredentialsService = new CredentialsService(credentialStore);
authConfig.AddBasicAuthenticationWithClaimsOutput(userCredentialsService.Validate);
config.MessageHandlers.Add(new AuthenticationHandler(authConfig));

知道我做错了什么吗?

【问题讨论】:

    标签: wif claims-based-identity thinktecture-ident-model thinktecture


    【解决方案1】:

    使用 Fiddler,你会找到Method not found: no match for ctor signature,然后稍微搜索一下就会发现 IdentityModel 的作者this comment

    所需的签名存在于 System.IdentityModel.Tokens.Jwt 版本 2.0.0.0 中,但不再存在于版本 4.0.20622.1351 中

    你必须使用武士刀。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-12
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      • 2021-06-21
      • 2016-09-16
      • 1970-01-01
      相关资源
      最近更新 更多