0

我正在构建一个本机移动应用程序和多个 Web API 以支持本机应用程序的功能,我对我的 Web API 的所有请求都经过身份验证,所以我使用 IdentityServer3 和 ASP.Net Identity

我想为我的本机应用程序(Twitter和 Digits)使用社交登录提供程序,并且我希望本机应用程序负责使用 Twitter 进行身份验证,一旦通过身份验证,来自 Twitter 的外部访问令牌将可用于本机应用程序。现在,我想在我的 Identity Server 3 设置中提供端点以支持验证外部访问令牌并根据用户生成本地访问令牌?

使用 asp.net 身份和身份服务器 3 实现此目的的最佳方法是什么?

这篇博文的作者似乎正在解释我想要实现的目标,但是,他没有使用 identityserver3 http://bitoftech.net/2014/08/11/asp-net-web-api-2-外部登录-社交-登录-facebook-google-angularjs-app/

4

2 回答 2

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"
    });
}

帐户控制器:

[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");
}
于 2015-12-10T15:51:39.383 回答
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 是关键部分,因为这会在已登录主体和身份服务器之间建立链接。

这里有更多关于此的信息;

https://identityserver.github.io/Documentation/docsv2/configuration/identityProviders.html

于 2015-12-11T14:05:56.637 回答