IdentityServer3 を使用して基本ログイン (OAuth2) を要求するコードを次に示します。identityServer Web サイトで外部ログインと openId ログインを見つけることができます。
サーバ:
範囲:
new Scope
{
Name ="morhipo",
Type = ScopeType.Resource,
Claims = new List<ScopeClaim>
{
new ScopeClaim(Constants.ClaimTypes.Name),
new ScopeClaim(Constants.ClaimTypes.Email),
new ScopeClaim(Constants.ClaimTypes.FamilyName),
new ScopeClaim(Constants.ClaimTypes.GivenName),
new ScopeClaim(Constants.ClaimTypes.Gender),
new ScopeClaim(Constants.ClaimTypes.Id),
new ScopeClaim(Constants.ClaimTypes.PhoneNumber),
new ScopeClaim(Constants.ClaimTypes.Subject),
new ScopeClaim(Constants.ClaimTypes.AccessTokenHash),
new ScopeClaim(Constants.ClaimTypes.Role)
}
}
ユーザー:
new InMemoryUser{ Subject = "bob", Username = "bob", Password = "bob",
Claims = new Claim[]
{
new Claim(Constants.ClaimTypes.GivenName, "Bob"),
new Claim(Constants.ClaimTypes.Role, "Admin"),
new Claim(Constants.ClaimTypes.Role, "User"),
new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
new Claim(Constants.ClaimTypes.Email, "BobSmith@email.com"),
new Claim(Constants.ClaimTypes.Name, "Bob Smith"),
}
},
クライアント:
new Client
{
ClientName = "Silicon on behalf of Carbon Client",
ClientId = "carbon",
Enabled = true,
AccessTokenType = AccessTokenType.Jwt,
Flow = Flows.ResourceOwner,
ClientSecrets = new List<Secret>
{
new Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256())
},
AllowedScopes = new List<string>
{
Constants.StandardScopes.OpenId,
Constants.StandardScopes.Profile,
Constants.StandardScopes.Email,
Constants.StandardScopes.Roles,
Constants.StandardScopes.OfflineAccess,
"read",
"write",
"api1",
"morhipo"
},
}
MVC クライアント:
起動:
public void ConfigureAuth(IAppBuilder app)
{
AntiForgeryConfig.UniqueClaimTypeIdentifier = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = new PathString("/account/login"),
AuthenticationType = "Cookies"
});
}
アカウントコントローラー:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
TokenResponse token = await GetToken(model.Email, model.Password);
await SignInAsync(token);
return View(model);
}
private async Task<TokenResponse> GetToken(string user, string password)
{
var client = new TokenClient(
"https://localhost:44333/core/connect/token",
"carbon",
"21B5F798-BE55-42BC-8AA8-0025B903DC3B");
var result = await client.RequestResourceOwnerPasswordAsync(user, password, "morhipo api1 offline_access");
return result;
}
public async Task SignInAsync(TokenResponse token)
{
var claims = await ValidateIdentityTokenAsync(token);
var id = new ClaimsIdentity(claims, "Cookies");
id.AddClaim(new Claim("access_token", token.AccessToken));
id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(token.ExpiresIn).ToLocalTime().ToString()));
id.AddClaim(new Claim("refresh_token", token.RefreshToken));
Request.GetOwinContext().Authentication.SignIn(id);
}
private async Task<IEnumerable<Claim>> ValidateIdentityTokenAsync(TokenResponse token)
{
return await Task.Run<IEnumerable<Claim>>(() =>
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
var certString = "MIIDBTCCAfGgAwIBAgIQNQb+T2ncIrNA6cKvUA1GWTAJBgUrDgMCHQUAMBIxEDAOBgNVBAMTB0RldlJvb3QwHhcNMTAwMTIwMjIwMDAwWhcNMjAwMTIwMjIwMDAwWjAVMRMwEQYDVQQDEwppZHNydjN0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnTksBdxOiOlsmRNd+mMS2M3o1IDpK4uAr0T4/YqO3zYHAGAWTwsq4ms+NWynqY5HaB4EThNxuq2GWC5JKpO1YirOrwS97B5x9LJyHXPsdJcSikEI9BxOkl6WLQ0UzPxHdYTLpR4/O+0ILAlXw8NU4+jB4AP8Sn9YGYJ5w0fLw5YmWioXeWvocz1wHrZdJPxS8XnqHXwMUozVzQj+x6daOv5FmrHU1r9/bbp0a1GLv4BbTtSh4kMyz1hXylho0EvPg5p9YIKStbNAW9eNWvv5R8HN7PPei21AsUqxekK0oW9jnEdHewckToX7x5zULWKwwZIksll0XnVczVgy7fCFwIDAQABo1wwWjATBgNVHSUEDDAKBggrBgEFBQcDATBDBgNVHQEEPDA6gBDSFgDaV+Q2d2191r6A38tBoRQwEjEQMA4GA1UEAxMHRGV2Um9vdIIQLFk7exPNg41NRNaeNu0I9jAJBgUrDgMCHQUAA4IBAQBUnMSZxY5xosMEW6Mz4WEAjNoNv2QvqNmk23RMZGMgr516ROeWS5D3RlTNyU8FkstNCC4maDM3E0Bi4bbzW3AwrpbluqtcyMN3Pivqdxx+zKWKiORJqqLIvN8CT1fVPxxXb/e9GOdaR8eXSmB0PgNUhM4IjgNkwBbvWC9F/lzvwjlQgciR7d4GfXPYsE1vf8tmdQaY8/PtdAkExmbrb9MihdggSoGXlELrPA91Yce+fiRcKY3rQlNWVd4DOoJ/cPXsXwry8pWjNCo5JD8Q+RQ5yZEy7YPoifwemLhTdsBz3hlZr28oCGJ3kbnpW0xGvQb3VHSTVVbeei0CfXoW6iz1";
var cert = new X509Certificate2(Convert.FromBase64String(certString));
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidAudience = "https://localhost:44333/core/resources",
ValidIssuer = "https://localhost:44333/core",
NameClaimType ="name",
IssuerSigningTokens = new X509CertificateSecurityTokenProvider(
"https://localhost:44333/core",
cert).SecurityTokens
};
SecurityToken t;
ClaimsPrincipal id = tokenHandler.ValidateToken(token.AccessToken, validationParameters, out t);
var claimList =id.Claims.ToList();
claimList.Add(new Claim(ClaimTypes.Name, id.Identity.Name));
return claimList.AsEnumerable();
});
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
Request
.GetOwinContext()
.Authentication
.SignOut("Cookies");
return RedirectToAction("Index", "Home");
}