带有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)]
});
}