Yes, I'm explicitly passing the client_id
as a request parameter as part of every request---initial login request as well as subsequent refresh token grant requests.
Is this happening because I use the Login API as opposed to OAuth API?
Yes, I'm explicitly passing the client_id
as a request parameter as part of every request---initial login request as well as subsequent refresh token grant requests.
Is this happening because I use the Login API as opposed to OAuth API?
Changing the JWT lifetime in the tenant reflects in the lifetime of the access_token
obtained by exchanging refresh_token
.
For example, with the following config, here's what I get in my logs:
Token expires in 28475 {aud: "faa64edb-ecca-4acb-a35e-d83f395ac04e", iat: 1607337214, exp: 1607337244}
Refreshing tokens to avoid expiry {aud: "faa64edb-ecca-4acb-a35e-d83f395ac04e", iat: 1607337214, exp: 1607337244}
Token expires in 35999195 {aud: "faa64edb-ecca-4acb-a35e-d83f395ac04e", iat: 1607337215, exp: 1607373215}
I'm running FusionAuth v1.18.8
The access_token
that is first issued has the right expiry. Any access_token
received via exchanging refresh_token
has a 12 hour validity.
My tenant does have a 12 hour validity on the access_token
. However, any tenant setting should be overridden by the application-specific setting, is it not?
When exchanging a refresh_token
for an access_token
, I expect the resulting access_token
to have a validity as defined by the application.
However, this doesn't seem to be the case..
Currently, I'm not sure where the 12-hour duration for the JWT is coming from. Is this a default value? If so, how would I override it?
I think the difference between what you are doing and what I'm doing is that I'm creating accounts via APIs.
await fusionAuthClient.register({
registration: {
applicationId: clientId
},
user: {
email,
password,
data: {
hasPassword: true,
loginsCount: 0
}
}
})
When I do this, FusionAuth sends out a verification email to the user. However, when the user verifies their email by clicking the link in the verification email, the user.email.verified
webhook does not fire.
Also, the user.create
webhook does not fire when I register the user (create+register) as shown above.
What version are you running? v1.18.8
Did you get the emails? No. However, I get an email when I perform the webhook test.
Did you configure webhooks in both locations (under settings and tenants)? Yes
When I call the relevant APIs to create a user account, FusionAuth sends them a verification email. However, when they verify their account, my configured user.email.verified
webhook does not fire. I have also tried user.create
webhook and that does not work either.
I'm quite certain that the webhook itself has been configured correctly, since the webkhook test works as expected. It's just that it never automatically triggers when a user verifies their email. What am I doing wrong?
From my (layman's) standpoint, that feels a bit arbitrary
Is a Facebook login different from OIDC? Is there a good reason as to why FusionAuth is preventing these users from being able to login?
I added the following lambda, but I'm quite confident that the lambda function never runs.
// Using the response from Facebook Me API, reconcile the User and User Registration.
function reconcile(user, registration, facebookUser) {
user.firstName = facebookUser.first_name;
user.middleName = facebookUser.middle_name;
user.lastName = facebookUser.last_name;
user.fullName = facebookUser.name;
if (facebookUser.picture && !facebookUser.picture.data.is_silhouette) {
user.imageUrl = facebookUser.picture.data.url;
}
if (facebookUser.birthday) {
// Convert MM/dd/yyyy -> YYYY-MM-DD
var parts = facebookUser.birthday.split('/');
user.birthDate = parts[2] + '-' + parts[0] + '-' + parts[1];
}
if (!facebookUser.email) {
user.email = facebookUser.sub + '@no-email.twoseven.xyz';
console.info('Added missing email: \n' + JSON.stringify(facebookUser));
}
}
Whenever I perform a login with a Facebook account that has no email registered, I see the following in the event log:
...
8/28/2020 05:05:45 AM EDT Call the [https://graph.facebook.com/oauth/access_token] endpoint.
8/28/2020 05:05:45 AM EDT Endpoint returned status code [200]
8/28/2020 05:05:45 AM EDT The identity provider was unable to reconcile the email address. An email address is required to complete this request.
Any chance we can do this for Facebook on the latest version?
Sadly, that isn't a viable option for me. I spent a considerable amount of time on setting up email templates.. I don't want to lose those.
It would be great if we could export these non-user settings, and later re-import them. This might be a good case for setting up a Github issue/feature-request. I will go ahead and create that.
The reason for bulk deletion links to another question I asked recently. I imported 850K+ users recently, and given that I had not registered the users against all applications, I decided to delete all users and re-import.
Forgive me if I sound entitled, but I'm a bit perplexed by this..
In a standard FusionAuth deployment, as documented on fusionauth.io, this API is unusable if the search result exceeds 10,000 users? This would mean that nearly all of the APIs documented here are unusable without tweaking elasticsearch in one way or another..
Additionally, could you recommend what I should do if my total user count simply will not fit in memory?
When using the FusionAuth Login APIs, I noticed that I do not get back a refresh_token
if the user is not registered with the application that I'm currently logging them into. I was able to solve this issue by running a script to update the registration of all users to include this application. However, now that I'm trying to create new applications under the same tenant to test how my application behaves when JWT tokens expire, I find myself having to run my scripts again to update registrations of all users to include this new application.
This approach simply does not scale . Is there a setting that I'm missing wherein a user can be registered against all applications of a tenant---existing and future ones?
I'm trying to execute the following using @fusionauth/typescript-client
:
try {
const result = await fusionAuthClient.deleteUsers({
hardDelete: true,
queryString: 'tenantId:886090a4-dd49-44bd-b6ba-c2cbdc3e7d21'
})
total = result.response.total
} catch (e) {
console.error(e)
debugger
}
When I run the above, I get a statusCode: 503
with the following error in fusionauth-search.log
[Aug 08, 2020 10:22:56.873 AM][DEBUG][o.e.a.s.TransportSearchAction] [auth] [fusionauth_user][0], node[FAaAggPGSieF4t__1kgM5Q], [P], s[STARTED], a[id=fH-Q-YNpSWCbYywRSli7gQ]: Failed to execute [SearchRequest{searchType=QUERY_THEN_FETCH, indices=[fusionauth_user], indicesOptions=Ind
icesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', req
uestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, allowPartialSearchResults=true, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"from":9698,"size":500,"query":{"query_string":{"
query":"tenantId:886090a4-dd49-44bd-b6ba-c2cbdc3e7d21","fields":[],"type":"best_fields","default_operator":"or","max_determinized_states":10000,"enable_position_increments":true,"fuzziness":"AUTO","fuzzy_prefix_length":0,"fuzzy_max_expansions":50,"phrase_slop":0,"escape":false,"aut
o_generate_synonyms_phrase_query":true,"fuzzy_transpositions":true,"boost":1.0}},"sort":[{"_score":{"order":"desc"}},{"fullName":{"order":"desc"}},{"email":{"order":"desc"}}]}}] lastShard [true]
org.elasticsearch.transport.RemoteTransportException: [auth][127.0.0.1:9020][indices:data/read/search[phase/query]]
Caused by: java.lang.IllegalArgumentException: Result window is too large, from + size must be less than or equal to: [10000] but was [10198]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] ind
ex level setting.
at org.elasticsearch.search.DefaultSearchContext.preProcess(DefaultSearchContext.java:211) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.search.query.QueryPhase.preProcess(QueryPhase.java:113) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.search.SearchService.createContext(SearchService.java:603) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:550) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:351) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.search.SearchService.lambda$executeQueryPhase$1(SearchService.java:343) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.action.ActionListener.lambda$map$2(ActionListener.java:146) ~[elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:58) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.action.ActionRunnable$2.doRun(ActionRunnable.java:73) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:44) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:692) [elasticsearch-7.6.1.jar:7.6.1]
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-7.6.1.jar:7.6.1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) [?:?]
at java.lang.Thread.run(Thread.java:832) [?:?]
How do I efficiently delete all users of a tenant?
That seems to work. Thank you for the quick patch.
I have also replaced mysql with postgresql and continue to have the same issue.
I have set up FusionAuth using mysql on Ubuntu 20.04 using the DEB package.
Every time I try and create an application, I end up getting the following error. Is there some setting that I have not filled in elsewhere during setup?
FusionAuth v1.18.0
Jul 20, 2020 12:13:42.083 AM ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown
org.primeframework.mvc.parameter.convert.ConverterStateException: The primitive converter doesn't support String[] to Object conversion.
at org.primeframework.mvc.parameter.convert.converters.AbstractPrimitiveConverter.stringsToObject(AbstractPrimitiveConverter.java:59)
at org.primeframework.mvc.parameter.convert.AbstractGlobalConverter.convertFromStrings(AbstractGlobalConverter.java:89)
at org.primeframework.mvc.parameter.el.Accessor.convert(Accessor.java:152)
at org.primeframework.mvc.parameter.el.MemberAccessor.set(MemberAccessor.java:133)
at org.primeframework.mvc.parameter.el.Accessor.set(Accessor.java:90)
at org.primeframework.mvc.parameter.el.Expression.setCurrentValue(Expression.java:93)
at org.primeframework.mvc.parameter.el.DefaultExpressionEvaluator.setValue(DefaultExpressionEvaluator.java:132)
at org.primeframework.mvc.parameter.DefaultParameterHandler.setValues(DefaultParameterHandler.java:205)
at org.primeframework.mvc.parameter.DefaultParameterHandler.handle(DefaultParameterHandler.java:121)
at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:54)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:102)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:58)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:45)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at io.fusionauth.app.primeframework.FrontEndTenantWorkflow.perform(FrontEndTenantWorkflow.java:71)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:126)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.workflow.StaticResourceWorkflow.perform(StaticResourceWorkflow.java:97)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.parameter.RequestBodyWorkflow.perform(RequestBodyWorkflow.java:89)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:57)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at io.fusionauth.app.primeframework.CORSFilter.handleNonCORS(CORSFilter.java:291)
at io.fusionauth.app.primeframework.CORSFilter.doFilter(CORSFilter.java:223)
at io.fusionauth.app.primeframework.CORSRequestWorkflow.perform(CORSRequestWorkflow.java:48)
at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51)
at io.fusionauth.app.primeframework.FusionAuthMVCWorkflow.perform(FusionAuthMVCWorkflow.java:88)
at org.primeframework.mvc.workflow.DefaultWorkflowChain.continueWorkflow(DefaultWorkflowChain.java:44)
at org.primeframework.mvc.servlet.FilterWorkflowChain.continueWorkflow(FilterWorkflowChain.java:50)
at org.primeframework.mvc.servlet.PrimeFilter.doFilter(PrimeFilter.java:82)
at com.inversoft.maintenance.servlet.MaintenanceModePrimeFilter.doFilter(MaintenanceModePrimeFilter.java:59)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.inversoft.servlet.UTF8Filter.doFilter(UTF8Filter.java:27)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
My understanding is that if I were to use resource-owner-password-credentials grant, then I would be passing client credentials to FusionAuth from my backend. While doing so, I find that all client logins are occurring from the same backend IP address. Is there a way to log the real client IP rather than my backend IP?
For example, the /api/identity-provider/login
endpoint that we use to do social logins allows passing an ipAddress
parameter. Is there something similar for the /oauth2/token
endpoint?
I hope this isn't being considered as a hijack, but if one were to use option 3 (resource grant), is there a way to pass the IP address of the requester (x-forwarded-for
/ipAddress
)? The documentation does not discuss this.