下面是在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
您可以在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