L'esempio su AspNet.Security.OpenIdConnect.Server mi sembra sia un server di autenticazione che di risorse. Mi piacerebbe separare quelli. L'ho fatto.Separazione di server di autenticazione e risorse con AspNet.Security.OpenIdConnect: il pubblico?
Al Startup.Config del server di autenticazione, ho le seguenti impostazioni:
app.UseOpenIdConnectServer(options => {
options.AllowInsecureHttp = true;
options.ApplicationCanDisplayErrors = true;
options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.Issuer = new System.Uri("http://localhost:61854"); // This auth server
options.Provider = new AuthorizationProvider();
options.TokenEndpointPath = new PathString("/token");
options.UseCertificate(new X509Certificate2(env.ApplicationBasePath + "\\mycertificate.pfx","mycertificate"));
});
Ho un AuthorizationProvider scritte, ma non credo che sia rilevante per il mio numero attuale (ma possibilmente rilevante). Alla sua esclusione GrantResourceOwnerCredentials, ho hard-code un affermazioni principale in modo che convalida per ogni richiesta di token:
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification context)
{
var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
identity.AddClaim(ClaimTypes.Name, "me");
identity.AddClaim(ClaimTypes.Email, "[email protected]");
var claimsPrincipal = new ClaimsPrincipal(identity);
context.Validated(claimsPrincipal);
return Task.FromResult<object>(null);
}
Sul server risorsa, ho il seguente nella sua Startup.config:
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>
{
branch.UseOAuthBearerAuthentication(options => {
options.Audience = "http://localhost:54408"; // This resource server, I believe.
options.Authority = "http://localhost:61854"; // The auth server
options.AutomaticAuthentication = true;
});
});
su Fiddler, chiedo per un token, e ottengo uno:
POST /token HTTP/1.1
Host: localhost:61854
Content-Type: application/x-www-form-urlencoded
username=admin&password=aaa000&grant_type=password
Quindi, ora che io uso token di accesso per accedere a una risorsa protetta dal server di risorsa:
GET /api/values HTTP/1.1
Host: localhost:54408
Content-Type: application/json;charset=utf-8
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI.....
Ora ottengo questo errore - Convalida del pubblico non riuscita. Pubblico: "vuoto". Non corrispondeva a validationParameters.ValidAudience: 'http://localhost:54408' o validationParameters.ValidAudiences: 'null'.
Penso che il motivo sia perché non ho mai impostato un pubblico sul server di autenticazione (su app.UseOpenIdConnectServer (...)), quindi non penso abbia scritto le informazioni sul pubblico al token. Quindi ho bisogno di impostare un pubblico sul server di autenticazione (come quello che viene fatto in IdentityServer3), ma non riesco a trovare una proprietà sull'oggetto delle opzioni che mi consenta di farlo.
AspNet.Security.OpenIdConnect.Server richiede che l'autenticazione e la risorsa siano nello stesso server?
Sta impostando l'audience quando si mette insieme ClaimsPrincipal e, in caso affermativo, come?
Devo scrivere un validatore di pubblico personalizzato e collegarlo al sistema? (Spero che la risposta a questo sia no)
Grazie mille! Ora funziona! Ho usato l'opzione 1 perché potrei avere più di un pubblico in grado di richiedere i token di accesso. –
@MickaelCaruso Ho aggiornato la mia risposta per utilizzare 'ticket.SetResources' in quanto il parametro' resource' non sarà più supportato nativamente nella prossima beta (consultare https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect. Server/issues/186 per ulteriori informazioni). Smetteremo inoltre di utilizzare JWT come formato predefinito per i token di accesso: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/186 – Pinpoint
Grazie per la tua risposta, mi ha davvero aiutato. Il metodo GrantResourceOwnerCredentials è praticamente lo stesso, ma ho anche aggiunto l'identità identity.AddClaim (ClaimTypes.Name, "MyFullName"); Ma quando chiamo User.GetUserName() nel mio controller web api ottengo NULL? User.GetUserId() restituisce ciò che viene passato nella rivendicazione NameIdentifier. Come posso ottenere User.GetUserName per restituire i dati? – partyelite