Map IdentityServer 4声称为.NET MVC 4客户端

时间:2017-10-13 07:41:00

标签: c# asp.net-mvc-4 identityserver4

在本周我试图让我的客户端连接到我的IdentityServer 4。

在IdentityServer上,我实现了IProfileService,为用户设置了一些静态声明。

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        var principal = await _userClaimsPrincipalFactory.CreateAsync(user);

        var claims = principal.Claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

        context.IssuedClaims = claims;

        var claims2 = new List<Claim>
        {
            new Claim("role", "JustSpend.Employee"),
            new Claim("role", "JustSpend.Administrator"),
            new Claim("fullName", string.Format("{0} {1}", user.FirstName, user.LastName)),
            new Claim("canAccess", "JustSpend"),
            new Claim("canAccess", "APRA"),
            new Claim("canAccess", "SFVO")
        };

        context.IssuedClaims.AddRange(claims2);
    }

在MVC 4客户端,我有以下配置:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "NIC Identity",
            Authority = "http://localhost:5000", //ID Server
            ClientId = "JSpend",
            ResponseType = "id_token code",
            SignInAsAuthenticationType = "Cookies",
            RedirectUri = "http://localhost:57895/signin-oidc", //URL of website
            PostLogoutRedirectUri = "http://localhost:57895/",
            Scope = "openid profile offline_access",
            TokenValidationParameters = new TokenValidationParameters() { NameClaimType = "name", RoleClaimType = "role" },
            ClientSecret = "secret",
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    var discoveryClient = new DiscoveryClient("http://localhost:5000");
                    var doc = await discoveryClient.GetAsync();


                    // use the code to get the access and refresh token
                    var tokenClient = new TokenClient(
                        doc.TokenEndpoint,
                        "JSpend",
                        "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(doc.UserInfoEndpoint);

                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

                    // create new identity
                    var id = n.AuthenticationTicket.Identity;

                    //id.AddClaims(userInfoResponse.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);
                }
            }
        });

在userInfoResponse中检索索赔都很好。用户登录后,将重定向到AccountController(ExternalLoginCallback)。但索赔根本没有映射到控制器中的用户。 ExternalLoginCallback方法:

public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }

        // Sign in the user with this external login provider if the user already has a login
        var result = await _signInManager.ExternalSignInAsync(loginInfo, isPersistent: false);

        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
            case SignInStatus.Failure:
            default:
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
        }
    }

谁能帮助我?我整个星期都在寻找解决方案,如果我谷歌,所有的搜索结果都会变成紫色(如访问过)......

0 个答案:

没有答案