.NET Core中的WS-Fed无法识别声明

时间:2019-06-18 17:34:36

标签: c# asp.net-core identityserver4 ws-federation

带有SPA的.NET Core 3.0 Web API。我已经设法将WS-Fed配置到应用程序中(我希望它是默认的auth选项,但是为了保持话题状态,我将不得不单独处理该问题)。但是,我不知道如何将声明映射到策略。据我所知,我的Web应用程序甚至没有看到传入的声明。但是,如果我检查了WS-Fed请求(使用rcFederation SAML,WS-Fed和OAuth跟踪器Chrome扩展),我会看到以下内容:

<wa>wsignin1.0</wa><wctx>CfDJ8EDM5Nd0G5JJs8saEKjHJkooGs9x6SLThlpX9OxrE5JJxOC47qfFpcFh2fXNJJLPRH2iLq_g2HlHjQANaYkVn9FDkG7tvS-aKsWFwlEq4-krvTzBKqlD8wnvN_PPk...</wctx><wresult><t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"><t:Lifetime><wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2019-06-18T17:02:27.303Z</wsu:Created><wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2019-06-18T18:02:27.303Z</wsu:Expires></t:Lifetime><wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Address>https://localhost:5001/</wsa:Address></wsa:EndpointReference></wsp:AppliesTo><t:RequestedSecurityToken><saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_a7c95193-341a-437d-aa69-ccd02c9ee403" Issuer="http://etrak.com/adfs/services/trust" IssueInstant="2019-06-18T17:02:27.317Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"><saml:Conditions NotBefore="2019-06-18T17:02:27.303Z" NotOnOrAfter="2019-06-18T18:02:27.303Z"><saml:AudienceRestrictionCondition><saml:Audience>https://localhost:5001/</saml:Audience></saml:AudienceRestrictionCondition></saml:Conditions><saml:AttributeStatement><saml:Subject><saml:NameIdentifier>john.williams</saml:NameIdentifier><saml:SubjectConfirmation><saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod></saml:SubjectConfirmation></saml:Subject><saml:Attribute AttributeName="emailaddress" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims"><saml:AttributeValue>john.williams@etrak.com.com</saml:AttributeValue></saml:Attribute><saml:Attribute AttributeName="surname" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims"><saml:AttributeValue>Williams</saml:AttributeValue></saml:Attribute><saml:Attribute AttributeName="givenname" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims"><saml:AttributeValue>John</saml:AttributeValue></saml:Attribute><saml:Attribute AttributeName="Group" AttributeNamespace="http://schemas.xmlsoap.org/claims"><saml:AttributeValue>CN=AdminUsers,OU=Groups,DC=etrak.com,DC=com</saml:AttributeValue><saml:AttributeValue>CN=AnotherTest Prod,OU=Groups,DC=int,DC=etrak.com,DC=com</saml:AttributeValue><saml:AttributeValue>ABCApp_Admin_Dev</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" AuthenticationInstant="2019-06-18T10:53:38.774Z"><saml:Subject><saml:NameIdentifier>john.williams</saml:NameIdentifier><saml:SubjectConfirmation><saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod></saml:SubjectConfirmation></saml:Subject></saml:AuthenticationStatement><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><ds:Reference URI="#_a7c95193-341a-437d-aa69-ccd02c9ee403"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><ds:DigestValue>Tajh7RowAZ6Pp85uB+WGOzwJhH...</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>UHqln08XkYAHJY3.../ds:SignatureValue><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><X509Data><X509Certificate>MIIC5jCCAc6gAwIBAgIQJ6cBBiEPuZZLPGDy+XcdsjANBgkqhkiG9w0BAQsFADAvMS0wKwYDVQQDEyRBREZTIFNpZ25pbmcgLSBmZWRlcmF0aW9uLmVmd25vdy5jb20wHhcNMTkwNTE0MDgyNzU3WhcNMjAwNTEzMDgyNzU3WjAvMS0wKwYDVQQDEyRBREZTIFNpZ25pbmcgLSBmZWRlcmF0aW9uLmVmd25vdy5jb20wggEiMA...</X509Certificate></X509Data></KeyInfo></ds:Signature></saml:Assertion></t:RequestedSecurityToken><t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType><t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType><t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType></t:RequestSecurityTokenResponse></wresult>

========================
这是来自.NET Core Kestrel控制台

dbug: IdentityServer4.Validation.TokenValidator[0]
      Calling into custom token validator: IdentityServer4.Validation.DefaultCus
tomTokenValidator
dbug: IdentityServer4.Validation.TokenValidator[0]
      Token validation success
{
        "ValidateLifetime": true,
        "AccessTokenType": "Jwt",
        "ExpectedScope": "openid",
        "Claims": {
          "nbf": 1560877403,
          "exp": 1560881003,
          "iss": "https://localhost:5001",
          "aud": [
            "https://localhost:5001/resources",
            "WebApplication12API"
          ],
          "client_id": "WebApplication12",
          "sub": "66d62ac0-8802-4a8f-8fd0-959af6280ac9",
          "auth_time": 1560877403,
          "idp": "WsFederation",
          "scope": [
            "openid",
            "profile",
            "WebApplication12API"
          ],
          "amr": "external"
        }
      }
dbug: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Creating userinfo response
dbug: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Scopes in access token: openid profile WebApplication12API
dbug: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Scopes in access token: openid profile WebApplication12API
dbug: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Requested claim types: sub name family_name given_name middle_name nicknam
e preferred_username profile picture website gender birthdate zoneinfo locale up
dated_at
dbug: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Scopes in access token: openid profile WebApplication12API
info: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Profile service returned the following claim types: sub preferred_username
 name
dbug: IdentityServer4.Endpoints.UserInfoEndpoint[0]
      End userinfo request

Requested claim types: sub name family_name given_name middle_name nicknam e preferred_username profile picture website gender birthdate zoneinfo locale up

部分

我假设是因为我只是将WS-Fed身份验证添加到我的应用程序中。当您在VS2019中使用个人身份验证创建.NET Core API + SPA应用程序时,将使用IdentityServer中间件,并且我假设这些是默认的要求声明。再次,尽管我看不到任何从.NET Core方面“要求”我的证据。

我已经看到了Claims-based authorization in ASP.NET Core的“官方” Microsoft文档,但似乎表明您所需要做的就是在Startup.cs中添加映射,并在控制器上添加Authorize(Policy="PolicyName")。 / p>

所以我不确定在这里下一步需要做什么。我至少会包含与此任务相关的代码:

Startup.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApplication12.Data;
using WebApplication12.Models;

namespace WebApplication12
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<ApplicationUser>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt()
                .AddWsFederation(
                authenticationScheme: "WsFederation",
                displayName: "Click to Login",
                options =>
                {
                    // MetadataAddress represents the Active Directory instance used to authenticate users.
                    options.MetadataAddress = "https://etrak.com/federationmetadata/2007-06/federationmetadata.xml";

                    // Wtrealm is the app's identifier in the Active Directory instance.
                    // For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL:
                    options.Wtrealm = "https://localhost:5001/";

                });

            services.AddMvc(options => options.EnableEndpointRouting = false);
            services.AddAuthorization(options =>
            {
            //I am getting multiple group memberships back which is true, but I just need this group
                options.AddPolicy("Admin", policy =>
                      policy.RequireClaim("http://schemas.xmlsoap.org/claims/Group", "ABCApp_Admin_Dev"));

                      //I am testing to see if claims auth will work on a claim that just returns one value
                options.AddPolicy("OneUser", policy =>
                      policy.RequireClaim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", "John"));
            });

            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseCors(cors =>
           {
               cors.AllowAnyHeader();
               cors.AllowAnyMethod();
               cors.AllowAnyOrigin();
           });
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseAuthentication();
            app.UseIdentityServer();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }
    }
}

SampleDataController

 [Authorize(Policy = "OneUser")]
    [Route("api/[controller]")]
    public class SampleDataController : Controller
    {
        private static string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        [HttpGet("[action]")]
        public IEnumerable<WeatherForecast> WeatherForecasts()
        {

//Start: JustTrying
//Checking to see where the claims would be stored. This code didn't do anything for me
                var u = (User as ClaimsPrincipal).Claims;
                foreach (Claim c in u)
                {
                    var b = c;
                }
//end JustTrying
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    DateFormatted = DateTime.Now.AddDays(index).ToString("d"),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                });
            }

0 个答案:

没有答案