Как аутентифицировать запрос от приложения c # к приложению ASP.NET WebApi с поддержкой WIF, используя утверждение SAML

Я настроил сервер удостоверений ThinkTecture в качестве STS, настроил проект веб-API и использовал "личность и доступ " инструмент в Visual Studio и указал на мои метаданные федерации, чтобы включить федеративную аутентификацию с использованием WIF. Вот как выглядит связанная часть web.config:


    
      
        
      

    
        
        
                

      
        
          
            
          
          
            
          
        
      
      
      
    
  
  
    
      
      
    
  

Это прекрасно работает для аутентификации пользователей, которые используют API из браузера.

Теперь мне нужно вызвать тот же API из кода (C #) в клиентском приложении - давайте вызовем этот APIClient - используя HTTPClient.

Для этого я добавил это в web.config:


        
        
        

Я предположил, что если я добавлю обработчик токена SAML и добавлю подтверждение SAML в заголовок HTTP Authorize, WIF подберет его и подтвердит подлинность запроса.

Я могу вызвать STS для получения токена SAML, как описано в методе GetSamlToken здесь:введите описание ссылки здесь

Это дает мне утверждение SAML, которое я присоединяю к заголовку HTTPClient:

client.SetToken("SAML", AuthenticationHeader);

кудаAuthenticationHeader это утверждение SAML, которое я получил от сервера. Проблема в том, что веб-API неничего не делать с утверждением того же самого - как будто это неЯ даже не вижу этого, Все, что я получаю в ответ - это перенаправление на STS.

Что я делаю неправильно? Как я могу аутентифицироваться и вызывать мой защищенный метод web api из другого кода, не переключаясь на JWT и т. Д.?

Заранее спасибо за помощь!

- обновлено

Я добавил следующее в свой WebApiConfig.cs, как предложил @Brock:

public static void Register(HttpConfiguration config)
{
    // Cross Origin Resource Sharing
    //CorsConfig.RegisterCors(GlobalConfiguration.Configuration);
    CorsConfig.RegisterCors(config);


    //CorsConfiguration corsConfig = new CorsConfiguration();
    //corsConfig.AllowAll();
    //var corsHandler = new CorsMessageHandler(corsConfig, config);
    //config.MessageHandlers.Add(corsHandler);


    // authentication configuration for identity controller
    var authentication = CreateAuthenticationConfiguration();
    config.MessageHandlers.Add(new AuthenticationHandler(authentication));



    // ASP.Net web api uses NewtonSoft Json.net natively, 
    // the following line forces the web api to use the xml serializer instead of data contract serializer
    config.Formatters.XmlFormatter.UseXmlSerializer = true;

    log.Debug("Registering Web API Routes");


    // register api routes

}




private static AuthenticationConfiguration CreateAuthenticationConfiguration()
{
    var authentication = new AuthenticationConfiguration
    {
        ClaimsAuthenticationManager = new ClaimsTransformer(),
        RequireSsl = false,
        EnableSessionToken = true
    };

    #region IdentityServer SAML
    authentication.AddSaml2(
        issuerThumbprint: "F89C10B505E015774D02E323DEDA32878F794028",
        issuerName: "https://10.40.40.68/issue/wsfed",
        audienceUri: "http://localhost:41740/",//Constants.Realm,
        certificateValidator: System.IdentityModel.Selectors.X509CertificateValidator.None,
        options: AuthenticationOptions.ForAuthorizationHeader("SAML"),
        scheme: AuthenticationScheme.SchemeOnly("SAML"));
    #endregion

    #region Client Certificates
    authentication.AddClientCertificate(ClientCertificateMode.ChainValidation);
    #endregion

    return authentication;
}

Однако я все еще получаю 302 ответа. Вот как я делаю запрос:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;


var factory = new WSTrustChannelFactory(
    new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
    "https://10.40.40.68/issue/wstrust/mixed/username");
factory.TrustVersion = TrustVersion.WSTrust13;

factory.Credentials.UserName.UserName = "myusername";
factory.Credentials.UserName.Password = "password";

var rst = new RequestSecurityToken
{
    RequestType = RequestTypes.Issue,
    KeyType = KeyTypes.Bearer,
    TokenType = Thinktecture.IdentityModel.Constants.TokenTypes.Saml2TokenProfile11,
    AppliesTo = new EndpointReference("http://localhost:41740/")
};

var token = factory.CreateChannel().Issue(rst) as System.IdentityModel.Tokens.GenericXmlSecurityToken;

string myToken = token.TokenXml.OuterXml;

HttpClient client = new HttpClient(new HttpClientHandler
{
    ClientCertificateOptions = ClientCertificateOption.Automatic,
    AllowAutoRedirect = false
});

client.SetToken("SAML", myToken);
//client.SetBearerToken(myToken);

var resp = client.GetAsync("http://localhost:41740/api/clients", HttpCompletionOption.ResponseContentRead).Result;
Assert.IsTrue(resp.IsSuccessStatusCode);

Ответы на вопрос(1)

Ваш ответ на вопрос