The 2 biggest issues I have with the support are:
I submitted a question 6452.
Mailiming gave us something to try. I asked that the question not be closed because we had not had a chance to test out the solution. Now that we have and it doesn't work we need a different solution.
I don't want this to be charged against our annual support question total since I specifically asked that it not be closed.
Thank you
Hi @mailiming,
I did review that document earl and as you pointed out, the autosave parameter is not mentioned.
It might be helpful to other to to update the documentation.
Thanks
That fixed it. Thank you.
Is there mention of this in the documentation? If so, can you send a link?
Since this is a microservice that's part of our Microservice solution, I created a minimal repository using the Microservice Template and copied the notes service.
You should have everything you need to run it.
https://github.com/roger-cprops/CprOnAbp-Test
Hi,
I just gave you read access to the GitHub repository: https://github.com/cpr-ops/notes-service
When an entity in the database is updated through an API call to the repository UpdateAsync method, I would expect it to return the concurrencyStamp that's updated in the database in the response. However it's returning the concurrencyStamp that was sent in the request. It returns the updated lastModificationTime and lastModifierId so I'm not sure why it doesn't return the updated concurrencyStamp
I've only found similar problems to this in Discord and the Abp support questions but no resolution.
Steps to reproduce the issue:
public string ConcurrencyStamp { get; set; }
note.SetConcurrencyStampIfNotNull(concurrencyStamp);
return await _noteRepository.UpdateAsync(note);
Here's the PUT request payload: { clientId: "6df04165-acd7-18dd-7ccd-3a0d2bc61b4a" clientName: "Peyton Floris" concurrencyStamp : "dbca526c0d9f4b69b49a4cf992fc0079" text: "Something something" }
Here's the response payload { "clientId": "6df04165-acd7-18dd-7ccd-3a0d2bc61b4a", "clientName": "Peyton Floris", "text": "Something something", "concurrencyStamp": "dbca526c0d9f4b69b49a4cf992fc0079", "isDeleted": false, "deleterId": null, "deletionTime": null, "lastModificationTime": "2024-01-25T11:17:09.740494-06:00", "lastModifierId": "9bb21ac9-d3ac-887e-b521-3a0c9c5d08d6", "creationTime": "2023-11-27T09:40:40.03589", "creatorId": "9bb21ac9-d3ac-887e-b521-3a0c9c5d08d6", "id": "b5a37273-6cfc-3a7f-f4f3-3a0f239d6c90" } Here's the concurrency stamp showing in the database. Please note, I'm the only one hitting this database in test 75aeaf08163242128737360e611e1496
Hi,
We're woking on this but we need the HostTenantResolveContributer since we're getting the tenant from the url for our front-end application. For example: auth.agency1.mydomain.com the tenant is agency1.
We're also exposing some services via API and need to get a token. The request will have the tenant in the request header if it is not for the host. The tenant will be left off the request header if it is for the host.
We'll try temporarily following your suggestion but we'll need to put the HostTenantResolveContributer back. So please don't close this ticket until we have everything working.
Thank you,
Hi,
In the output I sent you, the Tenant was not passed because the admin userId is for the host (i.e. no tenant).
I've given you read access to the GitHub repositories oauth-api (.net API) & auth-server (Abp auth-server app)
I tried modifying the configmap for the nginx ingress controller and it still didn't work either with a tenant or without a tenant in the request.
Here's the postman request passing a tenant in node.js format . `const axios = require('axios');
let config = { method: 'post', maxBodyLength: Infinity, url: 'https://oauth.cloverleafcms.dev/Token?Tenant=TexasGuardians&ClientId=PublicAPI&ClientSecret=***&UserName=EddyFitz&Password=', headers: { } };
axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); });`
When I tried to get a token for a user in one of the SaaS tenants this is what's in the log for the AKS auth-server
024-01-08T14:27:23.291440312Z [14:27:23 INF] Request finished HTTP/1.1 GET http://authserver.cloverleafcms.dev/.well-known/jwks - - - 200 1652 application/json;charset=UTF-8 10.7121ms 2024-01-08T14:27:23.340415663Z [14:27:23 INF] Request starting HTTP/1.1 POST http://authserver.cloverleafcms.dev/connect/token application/x-[www-form-urlencoded 361](http://www-form-urlencoded 361) 2024-01-08T14:27:23.341995658Z [14:27:23 INF] The request URI matched a server endpoint: Token. 2024-01-08T14:27:23.342031258Z [14:27:23 INF] The token request was successfully extracted: { 2024-01-08T14:27:23.342038958Z "grant_type": "password", 2024-01-08T14:27:23.342043558Z "username": "EddyFitz", 2024-01-08T14:27:23.342050958Z "password": "[redacted]", 2024-01-08T14:27:23.342816056Z "scope": "address email phone profile roles AccountService IdentityService AdministrationService SaasService ClientService ServicesService ClientServiceQueryService UserInfoQueryService DocumentService GuardianshipService NotesService ContactService EngagementLogService DocTemplateService FinancialsService", 2024-01-08T14:27:23.342856056Z "client_id": "PublicAPI", 2024-01-08T14:27:23.346486645Z "client_secret": "[redacted]" 2024-01-08T14:27:23.346807644Z }. 2024-01-08T14:27:24.199496948Z [14:27:24 INF] The token request was successfully validated. 2024-01-08T14:27:24.212204810Z [14:27:24 INF] Executing endpoint 'Volo.Abp.OpenIddict.Controllers.TokenController.HandleAsync (Volo.Abp.OpenIddict.AspNetCore)' 2024-01-08T14:27:24.213356906Z [14:27:24 INF] Route matched with {action = "Handle", controller = "Token", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] HandleAsync() on controller Volo.Abp.OpenIddict.Controllers.TokenController (Volo.Abp.OpenIddict.AspNetCore). 2024-01-08T14:27:24.213624105Z [14:27:24 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy 2024-01-08T14:27:24.228731859Z [14:27:24 INF] Try to use LDAP for external authentication 2024-01-08T14:27:24.255050379Z [14:27:24 WRN] Ldap login feature is not enabled! 2024-01-08T14:27:24.257459872Z [14:27:24 INF] Try to use OAUTH for external authentication 2024-01-08T14:27:24.261001161Z [14:27:24 WRN] OAuth login feature is not enabled! 2024-01-08T14:27:24.515941685Z [14:27:24 INF] No user found matching username: EddyFitz 2024-01-08T14:27:24.566320632Z [14:27:24 INF] Executing ForbidResult with authentication schemes (["OpenIddict.Server.AspNetCore"]). 2024-01-08T14:27:24.566390331Z [14:27:24 INF] The response was successfully returned as a JSON document: { 2024-01-08T14:27:24.566416131Z "error": "invalid_grant", 2024-01-08T14:27:24.566422131Z "error_description": "Invalid username or password!", 2024-01-08T14:27:24.566426931Z "error_uri": "https://documentation.openiddict.com/errors/ID2024" 2024-01-08T14:27:24.566431731Z }. 2024-01-08T14:27:24.566436331Z [14:27:24 INF] AuthenticationScheme: OpenIddict.Server.AspNetCore was forbidden. 2024-01-08T14:27:24.566442731Z [14:27:24 INF] Executed action Volo.Abp.OpenIddict.Controllers.TokenController.HandleAsync (Volo.Abp.OpenIddict.AspNetCore) in 348.651ms 2024-01-08T14:27:24.579174992Z [14:27:24 INF] Executed endpoint 'Volo.Abp.OpenIddict.Controllers.TokenController.HandleAsync (Volo.Abp.OpenIddict.AspNetCore)' 2024-01-08T14:27:24.661847341Z [14:27:24 INF] Request finished HTTP/1.1 POST http://authserver.cloverleafcms.dev/connect/token application/x-[www-form-urlencoded 361](http://www-form-urlencoded 361) - 400 155 application/json;charset=UTF-8 1321.5275ms 20
Here's the code for the .net API that uses the IdentityModel.Client;
`using IdentityModel.Client; using OauthToken.Models;
namespace OauthToken.Services { public class TokenService : ITokenService { private readonly IConfiguration _configuration;
public TokenService(IConfiguration configuration)
{
_configuration = configuration;
}
public async Task<TokenRequestResponse?> GetAccessToken(string? Tenant, string ClientId, string ClientSecret, string UserName, string Password)
{
var apiEndpoint = _configuration.GetValue<string>("AuthServiceBaseUrl");
var Scope = _configuration.GetValue<string>("Scope");
var discoveryCache = new DiscoveryCache(apiEndpoint);
var disco = await discoveryCache.GetAsync();
var client = new HttpClient();
var passwordTokenRequest = new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = ClientId,
ClientSecret = ClientSecret,
UserName = UserName,
Password = Password,
Scope = Scope
};
if (Tenant != null) passwordTokenRequest.Headers.Add("__tenant", Tenant);
var tokenResponse = await client.RequestPasswordTokenAsync(passwordTokenRequest);
TokenRequestResponse tokenRequestResponse = new();
if (tokenResponse.IsError)
{
tokenRequestResponse.ErrorCode = (int)tokenResponse.HttpResponse.StatusCode;
tokenRequestResponse.Error = tokenResponse.ErrorDescription;
}
else
{
tokenRequestResponse.AccessToken = tokenResponse.AccessToken;
tokenRequestResponse.RefreshToken = tokenResponse.RefreshToken;
tokenRequestResponse.ExpiresIn = tokenResponse.ExpiresIn;
}
return tokenRequestResponse;
}
}
}`