当前位置: 首页 > 知识库问答 >
问题:

如何将已授权的用户重定向回identity server 4中的上一页。NET CORE?

余铭晨
2023-03-14

下面是在Auth Server和Client machine中添加的代码,如果需要更多信息,请发表评论。

启动。cs—身份验证服务器

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        var builder = services.AddIdentityServer(options =>
        {
            options.EmitStaticAudienceClaim = true;
        })
            .AddInMemoryIdentityResources(Config.IdentityResources)
            .AddInMemoryApiScopes(Config.ApiScopes)
            .AddInMemoryClients(Config.Clients)
            .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>() 
            /*.AddProfileService<ProfileService>()*/;

        builder.AddDeveloperSigningCredential();



        services.AddTransient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();
        //services.AddTransient<IProfileService, ProfileService>();
    }

启动。cs—客户端应用程序

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.Authority = "https://localhost:44356/";
            options.ClientId = "TestIdpApp";
            options.ResponseType = "code";
            //options.UsePkce = false;
            //options.CallbackPath = new PathString("...")                
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.SaveTokens = true;
            options.ClientSecret = "secret";
        });
    }

ResourceOwnerPasswordValidator。cs—身份验证服务器

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        try
        {
            UserInfo user = await GetUserDetails(context.UserName, context.Password).ConfigureAwait(false);
            if (user != null && string.IsNullOrEmpty(user.ErrorMessage))
            {
                //set the result
                context.Result = new GrantValidationResult(
                    subject: user.UserId.ToString(),
                    authenticationMethod: "custom",
                    claims: GetUserClaims(user));
                return;
            }

            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, user.ErrorMessage);
            return;
        }
        catch (Exception ex)
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Invalid username or password");
        }
    }

    //build claims array from user data
    public static Claim[] GetUserClaims(UserInfo user)
    {
        return new Claim[]
        {
        new Claim("user_id", user.UserId.ToString() ?? ""),
        new Claim(JwtClaimTypes.Name, (!string.IsNullOrEmpty(user.FirstName) && !string.IsNullOrEmpty(user.Surname)) ? (user.FirstName + " " + user.Surname) : ""),
        new Claim(JwtClaimTypes.GivenName, user.FirstName  ?? ""),
        new Claim(JwtClaimTypes.FamilyName, user.Surname  ?? ""),
        new Claim(JwtClaimTypes.Email, user.Email  ?? "")
        };
    }
}

登录逻辑---

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginInputModel model, string button)
    {
        // check if we are in the context of an authorization request
        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);




        if (button == "reset")
        {
            return Redirect("ResetPasswordWithoutCode");
        }
        else
        {
            // the user clicked the "cancel" button
            if (button == "cancel")
            {
                if (context != null)
                {
                    // if the user cancels, send a result back into IdentityServer as if they 
                    // denied the consent (even if this client does not require consent).
                    // this will send back an access denied OIDC error response to the client.
                    await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);



                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
                    if (context.IsNativeClient())
                    {
                        // The client is native, so this change in how to
                        // return the response is for better UX for the end user.
                        return this.LoadingPage("Redirect", model.ReturnUrl);
                    }



                    return Redirect(model.ReturnUrl);
                }
                else
                {
                    // since we don't have a valid context, then we just go back to the home page
                    return Redirect("~/");
                }
            }



            if (ModelState.IsValid)
            {
                ResourceOwnerPasswordValidationContext context1 = new ResourceOwnerPasswordValidationContext();
                context1.UserName = model.Username;
                context1.Password = model.Password;
                // validate username/password against in-memory store
                await _resourceOwner.ValidateAsync(context1);



                if (context1.Result.Subject!=null && context1.Result.Subject.Identity.IsAuthenticated)
                {
                    var user = await ResourceOwnerPasswordValidator.GetUserDetails(model.Username,model.Password).ConfigureAwait(false);
                    await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.UserId, user.Username, clientId: context?.Client.ClientId));



                    // only set explicit expiration here if user chooses "remember me". 
                    // otherwise we rely upon expiration configured in cookie middleware.
                    AuthenticationProperties props = null;
                    if (AccountOptions.AllowRememberLogin && model.RememberLogin)
                    {
                        props = new AuthenticationProperties
                        {
                            IsPersistent = true,
                            ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
                        };
                    };



                    // issue authentication cookie with subject ID and username
                    var isuser = new IdentityServerUser(user.UserId)
                    {
                        DisplayName = user.Username
                    };

                    await HttpContext.SignInAsync(isuser, props);

                    if (context != null)
                    {
                        if (context.IsNativeClient())
                        {
                            // The client is native, so this change in how to
                            // return the response is for better UX for the end user.
                            return this.LoadingPage("Redirect", model.ReturnUrl);
                        }

                        // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
                        return Redirect(model.ReturnUrl);
                    }

                    // request for a local page
                    if (Url.IsLocalUrl(model.ReturnUrl))
                    {
                        return Redirect(model.ReturnUrl);
                    }
                    else if (string.IsNullOrEmpty(model.ReturnUrl))
                    {
                        return Redirect("~/");
                    }
                    else
                    {
                        // user might have clicked on a malicious link - should be logged
                        throw new Exception("invalid return URL");
                    }
                }



                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId: context?.Client.ClientId));
                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
            }



            // something went wrong, show form with error
            var vm = await BuildLoginViewModelAsync(model);
            return View(vm);
        }
    }

我正在调用一个webapi来检查凭据,并返回有关用户的信息,比如名字和姓氏。

https://localhost:44356/Account/Login?ReturnUrl=/connect/authorize/callback?client_id=TestIdpApp&redirect_uri=https%3A%2F%2Flocalhost%3A44335%2Fsignin-oidc&response_type=code&scope=openid%20profile&code_challenge=LEZaLWC8ShzJz6LGUsdeUPr974clsUSYVPXWDNmbwOE&code_challenge_method=S256&response_mode=form_post&nonce=637360236231259886.MmIxNjlhODMtZTJhYy00YzUzLTliYjMtZWJmNzM3ZjRiM2VlZmYwYzI2MDAtNWRjYS00NThlLWI4MjAtY2ViYjgxY2RlYmZi&state=CfDJ8LFJDL-5o71Ao2KksnBDgPVrH1DIIiM9LZSGUG43HRwLS6OjGUiGPwZ_xxT1RVryTZh7z3zwezVbdiy1L94mFlWausuYQrDNTWtzxrpTf2CrKjHRjcUIyNt5tX_g-yZYkWvxzCiyrpxnp7cctbNGoCmj_kqidhxCWsZee_26c3eVqfJfH7XEDfKUMj2BHeKQe_Ar9f2SkZJ0SBuy6MBe6zpU7-DDOYotDn-oO5zrtaHL8GCZfSqckqalL5yaGeolZ1ZDcubY01InyrBh1NwlVQRdGZRRWIZ-WnqqFKrTboQyw4rQswR-7BaLTtL8QitRkUmwS17LBLUvXKRBs8C0NUsX9HyREnmCVG2qW6s2AVpnE4iSt4XVSRcY-crXml2FjA&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0

共有1个答案

严信瑞
2023-03-14

您可以在GET登录操作中有这样的内容:

if (this.User.Identity.IsAuthenticated)
{
    return Redirect(returnUrl);
}
 类似资料:
  • 我正在使用ApacheShiro开发JSF应用程序。我用Shiro引诱用户,并将其重定向到主页。这没有问题。验证后,当我尝试访问登录页面时,它不会将我重定向到主页。即使已经有loggedin用户,我也可以再次登录。正如巴卢斯克在他的博客文章中提到的,我正在进行程序登录。 这个滤镜是根据博文写的。 } 问题是什么?如果用户已经通过身份验证,我该如何重定向用户? 编辑:现在,如果用户已经通过身份验证,

  • 我正在使用Laravel 5.3,我这里有一个情况。。。我在第2页,从那里注销,然后重定向到登录页。现在,如果用户再次登录,我试图实现的是重定向回第2页。 当前的情况是,用户将被重定向到defaultAfterLogin页面,这不是我想要的登录流。 注意:登录后的默认页面为"DashBoard"。 如果您第一次进入第2页(不是默认的仪表板页面),并且如果您未登录,您将被重定向到登录页面,那么如果您

  • 问题内容: 在我尝试编写的应用程序中,主页(http:// localhost:8675)具有以下形式: 这是server.js中的代码: 我希望能在不需要知道主机地址的地方进行处理,因为这种情况可能会发生变化。 “ http”对象是常规的require(’http’),而不是require(’express’)。 问题答案:

  • 我正在使用Spotify API开发一个应用程序,但我对这一切还是有点陌生。我正在尝试获取用于代码交换(PKCE)的带验证密钥的授权代码(https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-代码流和代码交换pkce的验证密钥)我的问题是如何将用户重定向到,在那里他

  • 我有一个页面,上面有一些内容和评论部分。评论只能由已登录的用户留下,因此我在页面中添加了一个登录表单供用户登录(仅当用户尚未登录时显示)。 我的问题是,当用户登录时,他们会被重定向回主页,而不是他们以前所在的页面。 我没有更改开箱即用设置的登录方法。 任何人都可以建议一个简单的方法来设置重定向url。我的想法是,能够将其设置为表单会很好。

  • 我不知道如何(或者在哪里)从AWS向用户授予读写权限,这样用户就可以在生产环境中的sample_app上发布图片。这是第11章的最后一个任务,它没有被教程覆盖,我在任何地方都找不到解决方案。 这是文件: 这是教程中的过程: 1)创建AWS IAM用户并记录访问和密钥-完成 2) 创建S3 bucket-完成 3) 向在上一步中创建的用户授予读写权限-如何授予??? 4) 然后运行以下三个命令: 5