【问题标题】:ADFS 2.0 Windows 2008 R2 Web APIADFS 2.0 Windows 2008 R2 Web API
【发布时间】:2014-08-05 13:11:18
【问题描述】:

我想制作一个与 Web API 应用程序对话的 MVC Web 应用程序,并使用 ADFS 2.0(在 Windows 2008 R2 上)进行身份验证。

我设法让 MVC Web 应用程序使用 ADFS 进行身份验证。

问:但我不知道应该如何将我的 ADFS 2.0(在 Windows 2008 R2 上)从 MVC Web 联合到 Web API(假设它们将部署在不同的服务器中)?

我发现了很多关于如何使用 WCF 或 Windows Server 2012 R2 执行此操作的文章,但没有使用 Windows Server 2008 R2 中的 Web API 和 ADFS 2.0


编辑,最后我选择了poor man delegation(将我收到的相同令牌传递到前端到后端(因为再次调用 adfs 没有意义)

FrontEnd -> 调用 GetToken 并放入授权标头(我将其编码为 base64)

public string GetToken()
{
    BootstrapContext bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext;
    string token = bootstrapContext.Token;

    if (string.IsNullOrEmpty(token))
        token = ToTokenXmlString(bootstrapContext.SecurityToken as SamlSecurityToken);

    return token;
}

string ToTokenXmlString(SecurityToken token)
{
    var genericToken = token as GenericXmlSecurityToken;

    if (genericToken != null)
        return genericToken.TokenXml.OuterXml;

    var handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
    return ToTokenXmlString(token, handler);
}

string ToTokenXmlString(SecurityToken token, SecurityTokenHandlerCollection handler)
{
    if (!handler.CanWriteToken(token))
        throw new InvalidOperationException("Token type not suppoted");

    var sb = new StringBuilder(128);
    using (StringWriter stringWriter = new StringWriter(sb))
    {
        using (var textWriter = new XmlTextWriter(stringWriter))
        {
            handler.WriteToken(textWriter, token);
            return sb.ToString();
        }
    }
}

后端->解析并验证令牌->

public ClaimsIdentity GetIdentityFromToken(string tokenBase64)
{
    if (string.IsNullOrEmpty(tokenBase64))
        return null;

    byte[] tokenByteArray = Convert.FromBase64String(tokenBase64);
    string decodedToken = Encoding.UTF8.GetString(tokenByteArray);

    if (string.IsNullOrWhiteSpace(decodedToken))
        return null;
    try
    {
        var handlers = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers;
        SecurityToken token;
        using (StringReader stringReader = new StringReader(decodedToken))
        {
            using (XmlTextReader xmlReader = new XmlTextReader(stringReader))
            {
                token = handlers.ReadToken(xmlReader);
            }
        }

        if (token == null)
            return null;

        return handlers.ValidateToken(token).FirstOrDefault();
    }
    catch (Exception e)
    {
        logger.Error(new AuthenticationException("Error validating the token from ADFS", e));

        return null;
    }
}

【问题讨论】:

    标签: asp.net-mvc asp.net-web-api single-sign-on windows-server-2008-r2 adfs


    【解决方案1】:

    我通过将我从 Adfs 收到的不记名令牌传递到 web api 调用的授权标头中来实现这一点,然后在 owin 期间使用 Microsoft.Owin.Security.Jwt nuget 包将令牌转换为 httpcontext 当前身份在 web api 项目中启动。

    此示例使用 jwt 令牌作为不记名令牌。为您要使用的令牌类型选择适当的 NuGet 包。

    在mvc控制器中构造WebRequest

     BootstrapContext bc = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext;
     HttpWebRequest request = WebRequest.Create(ConfigurationManager.AppSettings["ApiUrl"]) as HttpWebRequest;
     request.Method = "GET";
     request.Headers["Authorization"] = "Bearer " + bc.Token;
    

    Web api 中的 Owin Startup.cs 文件 在 app.UseWebApi(config) 行之前。

     app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    AllowedAudiences = new[] { ConfigurationSettings.AppSettings["ida:Realm"] },
                    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
                        { 
                            new SymmetricKeyIssuerSecurityTokenProvider(
                                ConfigurationSettings.AppSettings["ida:ValidIssuer"],
                                ConfigurationSettings.AppSettings["ida:SymmetricKey"])
                        },
                    Provider = new OAuthBearerAuthenticationProvider
                    {
                        OnValidateIdentity = context =>
                        {
                            return System.Threading.Tasks.Task.FromResult<object>(null);
                        }
                    }
                });
    

    【讨论】:

    • 问题是不能让ADFS 2008 R2发送JWT token,有时bc.Token为null。如果您有兴趣查看我使用的解决方案的编辑
    猜你喜欢
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多