我正在构建本机移动应用程序和多个Web API以支持本机应用程序的功能,我对我的Web API的所有请求都进行了身份验证,因此我使用IdentityServer3和ASP.Net Identity
我想将社交登录提供程序用于我的原生应用程序(Twitter和数字),我希望本机应用程序能够使用Twitter进行身份验证,一旦通过身份验证,Twitter上的外部访问令牌就可以使用本机应用程序。现在,我想在我的Identity Server 3设置中提供端点,以支持验证外部访问令牌并根据用户生成本地访问令牌?
使用asp.net身份和身份服务器3实现这一目标的最佳方式是什么?
这篇博客文章的作者似乎正在解释我想要实现的目标,但是,他没有使用identityserver3 http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/
答案 0 :(得分:0)
以下是一些使用IdentityServer3声明基本登录的代码(OAuth2) 您可以在identityServer网站上找到外部登录和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"
});
}
AccountController:
[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");
}
答案 1 :(得分:0)
您需要让Identity Server了解社交登录提供程序。您可以通过在IdentityServerOptions的AuthenticationOptions上将它们注册为IdentityProviders来执行此操作。
例如添加Facebook身份验证;
Install-Package Microsoft.Owin.Security.Facebook -Version 2.1.0
public static void Configuration(IAppBuilder appBuilder)
{
appBuilder.Map("/core", builder =>
{
builder
.UseIdentityServer(new IdentityServerOptions
{
AuthenticationOptions = new AuthenticationOptions
{
IdentityProviders = (app, signInAsType) =>
app.UseFaceBookAuthentication(
new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
Caption = "Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = "...",
AppSecret = "..."
}
}
}));
}
}
将提供者上的SignInAsAuthenticationType属性设置为signInAsType是关键部分,因为这将建立已登录的prin都与身份服务器之间的链接。
此处有更多相关信息;
https://identityserver.github.io/Documentation/docsv2/configuration/identityProviders.html