Use Ionic for JHipster to Create Mobile Apps with OIDC Authentication

Use Ionic for JHipster to Create Mobile Apps with OIDC Authentication

This article shows you how to use Ionic for JHipster to create a hybrid mobile app that runs on your phone. It supports JWT authentication, as well as OAuth 2.0 / OIDC. It even works with JHipster microservices!

Bruce Robinson

Ran into an issue running ionic serve for the first time but resolved it by adding http://localhost:8100 as Origin URL and as another Login redirect URI in okta… is this due to some new update perhaps, or did I mess something up? Also, I couldn’t login through the iOS simulator, it just goes blank. Otherwise good tutorial, thanks.

Matt Raible

Hello Bruce - adding http://localhost:8100 is specified in this tutorial, so it seems you just missed a step when you created your app in Okta. As far as iOS Simulator is concerned, you have to change JHipster to run on a different port because it seems that iOS Simulator runs on port 8080. The following note tells you this when you first create your Ionic app.

WARNING: The emulator runs on port 8080, so you will need to change your backend to run on a different port 
(e.g., 9080) when running ionic cordova emulate. Port 8080 is specified in the following files:

gateway/src/main/resources/config/application-dev.yml
ionic4j/src/providers/api/api.ts

Bruce Robinson

Yes, adding 8100 as a valid redirect URI was covered in the tutorial, I meant to emphasize that I had to also add it as a CORS Origin URL in the okta console, which I don’t think I see here? I also fixed my iOS issue - I did correctly change the backend port to 8888 as instructed, but I left the /api part in the API_URL string in ionic4j/src/providers/api/api.ts which caused an error trying to log in.

Matt Raible

When you add the redirect URIs in the initial app setup, it creates Trusted Origins for you. If you do it after, there’s nothing that automates creating the Trusted Origins, which is probably why you ran into this issue. I’m glad to hear you got it all working!

Spamtar

Can I add social login?

Matt Raible

Yep! You can configure Social Login in your Okta tenant and “Sign in with X” buttons will appear on your login form. https://developer.okta.com/…

Spamtar

With “jhipsterVersion”: "5.0.0-beta.1"
after ionic serve when I hit the http://localhost:8100 page I get error:
TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Matt Raible

What version of the Ionic Module for JHipster are you using? I just tried with v3.2.0 and was unable to reproduce the problem. Are you sure your backend app is running? If so, can you login to it? If so, please confirm that http://localhost:8080/api/auth-info returns your expected Okta settings.

Spamtar

I use v3.2.0 jhipster-ionic.
My backend is running and I can login on 8080.
When I call a fake url (http://localhost:8080/api/auth-info-fake-url ) I get 401 json “status” : 401.
When I call the http://localhost:8080/api/auth-info url I got 404. It seems there is no listening stuff on this url.

Matt Raible

The http://localhost:8080/api/auth-info endpoint should work. If it doesn’t, it means the installation of Ionic for JHipster didn’t work, or you’re not using OAuth in your backend application. Here’s the code that installs this endpoint: https://github.com/oktadeve…

Spamtar

Thank you the help!
The AuthInfoResource class was missing, other classes/security config were good. I fixed it, so when I call the auth-info url I get this:
{
“issuer” : “https://dev-774392.oktaprev…”,
“clientId” : “xxxxxxxxxxxxxxxxxxxx”,
“scope” : “openid profile email”
}

But the ionic problem still exist TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
What should I do? :confused:

Matt Raible

Whenever I’ve seen this issue in Ionic, it’s usually because a network request failed. I’d try using Chrome Developer Tools > Network to see which request is failing. Fix that, and everything should work.

Marlon Falzetta

Hi,

I see this erros at try login in Ionic app:

Failed to load resource: the server responded with a status of 404 (Not Found)
core.js:1449 ERROR HttpErrorResponse
defaultErrorLogger @ core.js:1449
:8080/api/account:1 Failed to load resource: the server responded with a status of 401 (Unauthorized)
polyfills.js:3 POST http://localhost:8080/api/authenticate 403 (Forbidden)

End this error in backend:

2018-05-28 12:37:05.932 DEBUG 13566 — [ XNIO-2 task-3] o.s.b.w.f.OrderedRequestContextFilter : Bound request context to thread: HttpServletRequestImpl [ POST /api/authenticate ]
2018-05-28 12:37:05.933 WARN 13566 — [ XNIO-2 task-3] o.z.p.spring.web.advice.AdviceTrait : Forbidden: Invalid CSRF Token ‘null’ was found on the request parameter ‘_csrf’ or header ‘X-XSRF-TOKEN’.
2018-05-28 12:37:05.935 WARN 13566 — [ XNIO-2 task-3] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token ‘null’ was found on the request parameter ‘_csrf’ or header ‘X-XSRF-TOKEN’.
2018-05-28 12:37:05.935 DEBUG 13566 — [ XNIO-2 task-3] o.s.b.w.f.OrderedRequestContextFilter : Cleared thread-bound request context: HttpServletRequestImpl [ POST /api/authenticate ]

Im my backend the class ResourceServerConfiguration not exists and a endpoint /api/auth-info not exists in both backend end ionic app.

Obs.: I dont use OKTA, i use keycloak.

Someone can help-me?

Matt Raible

As far as I can tell, your backend is using JWT authentication. The /api/authenticate endpoint does not exist when you’re using OAuth / OIDC authentication. If you want to use Keycloak, you’ll need to re-create your backend with an authentication type of OAuth.

Marlon Falzetta

Hi Matt, thanks for your reply.

I repeat the creation process using Monolithic and OAuth 2.0, please see attachement, and in my new backend exists authenticate endpoint.

@GetMapping("/authenticate")
@Timed
public String isAuthenticated(HttpServletRequest request) {
log.debug(“REST request to check if the current user is authenticated”);
return request.getRemoteUser();
}

And, yes, i use Keycloak end its work fine in my computer. Works fine with docker and standalone install.

If you can analise my instalation log please, I would appreciate.

Regards.

https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c…

https://uploads.disquscdn.c…

Matt Raible

It looks like you have CSRF turned on. The ResourceServerConfiguration that JHipster for Ionic installs disables CSRF for all “/api/**” endpoints. Did you customize JHipster and turn it on? If not, please create an issue in the JHipster for Ionic project with steps to reproduce.

Marlon Falzetta

In my backend, dont existis class ResourceServerConfiguration.

Security configurations exists in SecurityConfiguration as below:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler())
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/profile-info").permitAll()
.antMatchers("/api/").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/
").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN);

}

After execute yo jhipster-ionic, its install ResourceServerConfiguration? In my case dont install.

I see your link for ResourceServerConfiguration and try replace code below for:

http
.csrf().disable()
.addFilterBefore(corsFilter, CsrfFilter.class)
.requestMatcher(new RequestHeaderRequestMatcher(“Authorization”))
.authorizeRequests()
.antMatchers("/api/
").authenticated()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN);

But i get error.

Matt Raible

Please create an issue in the Ionic for JHipster project. Make sure to include the output of jhipster info from your JHipster project in the issue. Thanks!

Marlon Falzetta

Ok. Open at https://github.com/oktadeve…

Thank you so much.