Hi, I have 2 applications: application A and application B, both applications were created using abp suite with the options as below:
- ABP Framework version: v3.3.2
- UI type: Angular
- Identity Server Seperated (Angular): yes
I want user from application A can login into application B, so I have created client id and client secret in Identity Server A and added Identity Server A as external authentication provider in Identity Server B:
context.Services.AddAuthentication()
.AddOpenIdConnect("oidc", "Intranet OpenID Connect", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://localhost:44306/";
options.ClientId = "internetprovider";
options.ClientSecret = "R73vz3w4ttIAhETTO2xp/FW5b2m90nPw0aLvOvA50d4=";
options.ResponseType = "code";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
})
the login option is shown in Identity Server B login page:
However, I got timeout error when trying to click the above button, this is the log content: https://drive.google.com/file/d/1VEQzShv4mI3tLc1ZbiAXi6OqOZuKNXY-/view?usp=sharing
17 Answer(s)
-
0
Hi, I managed to make the login working by changing the code below:
context.Services.AddAuthentication() .AddOpenIdConnect("oidc", "Intranet OpenID Connect", options => { options.Authority = "https://localhost:44306/"; options.ClientId = "internetprovider"; options.ResponseType = OpenIdConnectResponseType.CodeIdToken; options.ClientSecret = "secret"; options.RequireHttpsMetadata = false; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("email"); })
the page had navigated to the Identity Server A login page, I logged in successfully, however, it keeps navigate back to the Identity Server B login page, it should redirect me to application page or registration page if user is new.
This is the client configuration in Identity Server A:
Any help is appreciated
-
0
Hello @nhontran,
the login option is shown in Identity Server B login page:
Can you check if you have returnUrl parameter on your address bar after navigated to Application A Login Page?
the page had navigated to the Identity Server A login page, I logged in successfully, however, it keeps navigate back to the Identity Server B login page, it should redirect me to application page or registration page if user is new.
User will already be registered with external provider, this is some different page for business rule i assume.
Either return url is not set or getting lost at the flow. Need more info to check it. But you can also modify the flow as you like with overriding the LoginPage of Application B like explained in this article.
For example, you can override this method below and check or manipulate to redirect to your dashboard whichever page you like.
public override Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null) { return base.OnGetExternalLoginCallbackAsync(returnUrl, returnUrlHash, remoteError); }
-
0
Hi @gterdem, yes, the returnUrl was in address bar after navigated to Application A login page:
https://localhost:44306/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dinternetprovider%26redirect_uri%3Dhttps%253A%252F%252Flocalhost%253A44366%252Fsignin-oidc%26response_type%3Dcode%26scope%3Dopenid%2520profile%2520email%26code_challenge....
- Identity Server B: localhost:44366
- Identity Server A: localhost:44306
Below is the log details in Identity Server B, there is a line "ModelState is invalid", could you help me check:
[00:41:39 INF] Request starting HTTP/2.0 POST https://localhost:44366/Account/Login?returnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fresponse_type%3Dcode%26client_id%3DinternetAbp_App%26state%3DNTdhV1BhekxYTjFQakFyMzAwWFhMeW9CRHAzVURfMEVUbk4weVl-aVZhZmtw%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A4200%26scope%3Dopenid%2520offline_access%2520internetAbp%26code_challenge%3DdQlDYtTlRIf4QVskwYTFtNSzSLEHKkZ2Vi5tLCO3nMk%26code_challenge_method%3DS256%26nonce%3DNTdhV1BhekxYTjFQakFyMzAwWFhMeW9CRHAzVURfMEVUbk4weVl-aVZhZmtw&handler=ExternalLogin application/x-www-form-urlencoded 651 [00:41:39 INF] CORS policy execution failed. [00:41:39 INF] Request origin https://localhost:44366 does not have permission to access the resource. [00:41:39 INF] No CORS policy found for the specified request. [00:41:39 INF] Executing endpoint '/Account/Login' [00:41:39 INF] Route matched with {page = "/Account/Login", area = "", action = "", controller = ""}. Executing page /Account/Login [00:41:39 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [00:41:39 INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.LoginModel.OnPostExternalLogin - ModelState is Invalid [00:41:39 INF] Executed handler method OnPostExternalLogin, returned result Microsoft.AspNetCore.Mvc.ChallengeResult. [00:41:39 INF] Executing ChallengeResult with authentication schemes (["oidc"]). [00:41:39 INF] AuthenticationScheme: oidc was challenged. [00:41:39 INF] Executed page /Account/Login in 136.7324ms [00:41:39 INF] Executed endpoint '/Account/Login' [00:41:39 DBG] Added 0 entity changes to the current audit log [00:41:39 DBG] Added 0 entity changes to the current audit log [00:41:39 INF] Request finished in 159.1755ms 302
-
0
Can you override OnPostExternalLogin method as the sample I mentioned to check what the ModelState is about?
-
0
Hi @gterdem, I have overrided the methods and found the root caue, the loginInfo is returned null if I login with the Identity Server A as authentication provider:
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { Logger.LogWarning("External login info is not available"); return RedirectToPage("./Login"); }
I have added Google authentication provider to check, it was able to retrieve the loginInfo and proceed redirect to /Register page to register new user while the Identity Server could not retrieve the info and redirected to /.Login page:
Google log:
[10:28:16 INF] Executing handler method internetAbp.Pages.Account.CustomLoginModel.OnGetExternalLoginCallbackAsync - ModelState is Valid [10:28:17 DBG] Added 0 entity changes to the current audit log [10:28:17 DBG] Added 0 entity changes to the current audit log [10:28:17 INF] Executed handler method OnGetExternalLoginCallbackAsync, returned result Microsoft.AspNetCore.Mvc.RedirectToPageResult. [10:28:17 DBG] Added 0 entity changes to the current audit log [10:28:17 INF] Executing RedirectToPageResult, redirecting to ./Register.
Identity Server A log:
[10:30:30 INF] Executing handler method internetAbp.Pages.Account.CustomLoginModel.OnGetExternalLoginCallbackAsync - ModelState is Valid [10:30:33 WRN] External login info is not available [10:30:33 INF] Executed handler method OnGetExternalLoginCallbackAsync, returned result Microsoft.AspNetCore.Mvc.RedirectToPageResult. [10:30:33 INF] Executing RedirectToPageResult, redirecting to ./Login. [10:30:33 INF] Executed page /Account/Login in 3398.5971ms [10:30:33 INF] Executed endpoint '/Account/Login'
Full Log:
- Google: https://drive.google.com/file/d/1twmxIq2_xMXNNMe5ejc8mTi4CmMQggJY/view?usp=sharing
- Identity Server A: https://drive.google.com/file/d/1UFc2TLSfSlx62mntxXHd2nkZJ_qMuIFz/view?usp=sharing
Could you please help me check.
-
0
@nhontran we couldn't reproduce it. is it possible to share a repro project with us send the link to info@abp.io with the question number.
-
0
Hi @alper, yes, I have shared the repo via email, please help take a look.
Thanks.
-
0
thanks we got your solution. it's under investigation.
-
0
Hi @alper, is there any updates on the investigation?
-
0
Hi @nhontran, thanks for your patience. We're still investigating it. I'll be inform you as soon as possible.
-
0
Hi @gterdem, did you manage to reproduce the issue? I have removed the repository due to license key found in the repo.
Please let me know if you need any further info.
-
0
Hi @nhontran,
I've reproduced
- Application B (Angular) trying to login, redirects to Application B IS
- Application B IS redirects to Application A IS after External Login Intranet OpenId Connect click
- After entering credentials Application A IS redirects to Application B IS login which means external login is not successful
- User is not externally registered to Application B IS
We're investigating this behaviour.
-
0
Hello @nhontran,
I found out that the miss configuration of Intranet OpenID Connect causes this behaviour.
You need to add:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // Mapping for GetExternalLoginInfoAsync since "sub" is used instead of "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
before <br>
context.Services.AddAuthentication() .AddOpenIdConnect("oidc", "Intranet OpenID Connect", options => {
so that provider key should not be null in the default signin manager implementation of GetExternalLoginInfoAsync. This causes chain failure of events which was really time consuming to figure out.
Key of notice, this is related with microsoft default oidc claim mapping issue, not related with ABP. Here is a related identityserver issue.
-
0
Hi @gterdem, noted. I will try and let you know. Thanks a lot
-
0
let us know and if it's OK close the issue pls.
-
0
Hi @gterdem, sorry for my late response, I have tried the fix suggested by you but it does not work, it still could not get the external login info
[00:08:12 INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.LoginModel.OnGetExternalLoginCallbackAsync - ModelState is Valid [00:08:12 INF] Identity.External was not authenticated. Failure message: Unprotect ticket failed [00:08:12 WRN] External login info is not available [00:08:12 INF] Executed handler method OnGetExternalLoginCallbackAsync, returned result Microsoft.AspNetCore.Mvc.RedirectToPageResult. [00:08:12 INF] Executing RedirectToPageResult, redirecting to ./Login.
Could you please help us take a look.
-
0
Hi @gterdem, sorry, I have set SignInScheme to another value when doing the verification.
Your suggestion has resolved the issue, thank you very much.