使用IdentityServer3进行Azure AD身份验证的本地帐户和选项

时间:2017-09-14 11:05:53

标签: c# azure-active-directory identityserver3

我是IdentityServer的新手。我们要求应用程序允许访问多个Web API。截至目前,身份验证是使用数据库在本地完成的,并且还有另一种方法可以通过Azure AD进行身份验证。

我希望我的仪表板应用程序使用IdentityServer3进行身份验证(目前工作正常),或者使用外部提供程序(在这种情况下为Azure AD)。

然而我一直在

  

确定您要登录的应用程序时出错。返回应用程序并再试一次

服务器的配置,我使用CustomViewService found at here

我将Azure AD添加到外部提供商列表中:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{

  ClientId = "xxxxxx-xxx-xxx-xx-04ec8dbxxxx",
  Authority = "https://login.windows.net/[domain name]",
  RedirectUri = "https://localhost:44333/core",
  PostLogoutRedirectUri = "http://localhost:36336/",
  AuthenticationType = "Azure AD",
  Caption = "Azure AD",
  TokenValidationParameters = new TokenValidationParameters
  {
    NameClaimType = "name",
    RoleClaimType = "role"
  },
  SignInAsAuthenticationType = "Cookies",

  Notifications = new OpenIdConnectAuthenticationNotifications
  {
    MessageReceived = m =>
    {
      var split = m.ProtocolMessage.AccessToken;
      return Task.FromResult(0);
    },
    AuthenticationFailed = context =>
    {
      context.HandleResponse();
      context.Response.Redirect("/Error?message=" + context.Exception.Message);
      return Task.FromResult(0);
    },
    RedirectToIdentityProvider = (context) =>
    {
      context.ProtocolMessage.DomainHint = "[domain name here]";
      return Task.FromResult(0);
    }
  }
});

我提供了Azure AD登录屏幕,然后将应用程序转移回https://localhost:44333/core/callback

上的IdentityServ3

我的客户位于http://localhost:36336/

客户端配置为:

public void Configuration(IAppBuilder app)
{
  // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
  JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

  app.UseCookieAuthentication(new CookieAuthenticationOptions
  {
    AuthenticationType = "Cookies"
  });

  app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
  {
    ClientId = "mvc.owin.hybrid.2",
    Authority = "https://localhost:44333/core",
    RedirectUri = "http://localhost:36336/",
    PostLogoutRedirectUri = "http://localhost:36336/",
    ResponseType = "code id_token",
    Scope = "openid profile read write offline_access",

    TokenValidationParameters = new TokenValidationParameters
    {
      NameClaimType = "name",
      RoleClaimType = "role"
    },

    SignInAsAuthenticationType = "Cookies",

    Notifications = new OpenIdConnectAuthenticationNotifications
    {
      AuthorizationCodeReceived = async n =>
      {
        // use the code to get the access and refresh token
        var tokenClient = new TokenClient(
        "https://localhost:44333/core/connect/token",
        "mvc.owin.hybrid.2",
        "secret");

        var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
        n.Code, n.RedirectUri);

        if (tokenResponse.IsError)
        {
          throw new Exception(tokenResponse.Error);
        }

        // use the access token to retrieve claims from userinfo
        var userInfoClient = new UserInfoClient(
        new Uri(n.Options.Authority + "/connect/userinfo"),
        tokenResponse.AccessToken);

        var userInfoResponse = await userInfoClient.GetAsync();

        // create new identity
        var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
        id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims);

        id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
        id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
        id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
        id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
        id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));

        n.AuthenticationTicket = new AuthenticationTicket(
        new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"),
        n.AuthenticationTicket.Properties);
      },

      RedirectToIdentityProvider = n =>
      {
        // if signing out, add the id_token_hint
        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
        {
          var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

          if (idTokenHint != null)
          {
            n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
          }
        }

        return Task.FromResult(0);
      }
    }
  });
}

1 个答案:

答案 0 :(得分:0)

管理完成它。

我忘了特别使用方法AspNetIdentityUserService

来实现AuthenticateExternalAsync

一旦我将用户和声明从Azure映射到它工作的本地用户。

此外,如果您需要隐藏本地登录屏幕并希望您的客户端直接转到Azure AD登录屏幕,请确保在客户端属性中将EnableLocalLogin设置为false