Я использую IdentityServer4, чтобы получить токены OpenId для моего веб-приложения.
Но мое веб-приложение использует Owin для безопасности. Я не могу найти примеры примеров того, где это делается.
Так что этот код работает;
В моем клиенте;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using SIR.API.Caller.Helpers;
namespace SIR.API.Caller
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = Settings.SignInAsAuthenticationType // "Cookies";
});
app.UseOpenIdConnectAuthentication(openIdConnectOptions: new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Authority = Settings.AuthorityUrl1, //ID Server, "https://localhost:44314/"; https://localhost:44307/
ClientId = Settings.ClientId, // "SIR"
Scope = Settings.Scope, // "openid profile";
ResponseType = Settings.ResponseType, // "id_token code";
SignInAsAuthenticationType = Settings.SignInAsAuthenticationType,
//--------------------------------------// "Cookies";
RedirectUri = Settings.RedirectUri, // URL of website, http://localhost:50000/signin-oidc;
//RedirectUri = Settings.RedirectUri1, // URL of website, http://localhost:53200/signin-oidc;
RequireHttpsMetadata = Settings.RequireHttpsMetadata,
//--------------------------------------// true
ClientSecret = "secret"
});
app.Use(async (ctx, next) =>
{
var message = ctx.Authentication.User.Identity.IsAuthenticated
? $"User: {ctx.Authentication.User.Identity.Name}"
: "User Not Authenticated";
await next();
});
}
}
}
На моем сервере ID 4 запускается:
using System.Security.Cryptography.X509Certificates;
using IdentityServer4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Mulalley.IdentityServer4.Helpers;
using QuickstartIdentityServer;
namespace Mulalley.IdentityServer4
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
//.AddDeveloperSigningCredential()
.AddSigningCredential(new X509Certificate2(Settings.CertPath, Settings.Password))
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
// register your IdentityServer with Google at https://console.developers.google.com
// enable the Google+ API
// set the redirect URI to http://localhost:port/signin-google
options.ClientId = "copy client ID from Google here";
options.ClientSecret = "copy client secret from Google here";
})
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://demo.identityserver.io/";
options.ClientId = "implicit";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
}
}
и Config.cs есть;
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;
namespace QuickstartIdentityServer
{
public class Config
{
// scopes define the resources in your system
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("SIR", "Service Inspection Report")
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
var baseUri = "http://localhost:53200/";
// client credentials client
return new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "SIR" },
AlwaysIncludeUserClaimsInIdToken = true
},
// resource owner password grant client
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "SIR" },
AlwaysIncludeUserClaimsInIdToken = true
},
// OpenID Connect hybrid flow and client credentials client (MVC)
new Client
{
ClientId = "SIR",
ClientName = "SIR",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { baseUri + "signin-oidc" },
PostLogoutRedirectUris = { baseUri + "signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"SIR"
},
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true
}
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Alice"),
new Claim("website", "https://alice.com")
}
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Bob"),
new Claim("website", "https://bob.com")
}
}
};
}
}
}
И вопрос в том, как мне получить токен в C #, чтобы я мог на него взглянуть? И как мне установить GetClaimsFromUserInfoEndpoint = true, который недоступен в OWIN?
Есть ли примеры кода, на которые я могу посмотреть с OWIN-доступом к ID4?
РЕДАКТИРОВАТЬ: Этот код, кажется, то, что мне нужно: https://identitymodel.readthedocs.io/en/latest/client/token.html
Однако я ввел код и получил токен доступа, который при вводе в jwt.io выдает сообщение «Недопустимая подпись».
private static async Task<TokenResponse> GetClientCredentialsTokenResponse()
{
var client = new HttpClient();
var tokenRequest = new ClientCredentialsTokenRequest
{
Address = Settings.AuthorityUrl1 + "connect/token",
ClientId = Settings.ClientId,
ClientSecret = "secret",
Scope = "SIR"
};
return await client.RequestClientCredentialsTokenAsync(tokenRequest);
}
private static async Task<TokenResponse> GetTokenResponse()
{
var client = new HttpClient();
var tokenRequest = new TokenRequest
{
Address = Settings.AuthorityUrl1 + "connect/token",
GrantType = GrantType.ClientCredentials,
ClientId = Settings.ClientId,
ClientSecret = "secret",
Parameters =
{
{"scope", "SIR"}
}
};
return await client.RequestTokenAsync(tokenRequest);
}
private static void ThrowResponseException(TokenResponse response)
{
const string message = "Problem accessing the UserInfo endpoint";
if (response.Exception == null)
{
throw new Exception($"{message}: {response.Error}. {response.ErrorDescription}.");
}
throw new Exception(message, response.Exception);
}
}
}