I am working through a process of validating the JWT after OKTA Login. I have a SPA Sample SPA Site that handles user login and calling an API.
SPA SITE
User Logins into OKTA
Obtains a JWT
Passes JWT to a .NET Web API (hosted on my own server not at OKTA).
WEB API: This accepts the JWT and needs to validate it.
Per OKTA I need verify the JWT through an Authorization Server. I setup the Authorization Server but I cannot see where the two features (shown on the images) are located on the SPA API or the Auth Server. This includes a URL that is required that follows the format of xxxx.okta.com/AS/{key}
Is there something that has to be enabled that is not enabled in my OKTA Account? I think so but what is it? OKTA support states that everything is enabled and confirmed this is a good code sample (GitHub) to use.
The Image Below should appear after setting up the SPA App. I cannot find this feature under the SPA or under the Auth Server. It does not seem to exist anywhere on OKTA. This is why it seems something is not enabled on my Dev account, or this documentation is outdated?
SPA Code Sample (includes the images below from the PDF) https://github.com/oktadeveloper/okta-oauth-spa-authjs-osw
I see that under the Security menu item -> API.
Also, when I had my app OpenID Connect enabled, I used well-known endpoint:
GET /.well-known/openid-configuration to get "jwks_uri", I used this url to self-verify the JWT token at the API level.
OKTA confirmed the code sample and documentation is out of date. They have no ETA to any updated samples and could not provide any documentation to help. This was via a response on a support ticket. Well already then, time to look at Azure.
Related
I'm having a hard time figuring a good way to implement Oauth 2.0 and OpenID Connect authentication alongside an existing internal email+password authentication for a B2B Web app's API using Spring security.
We have a backend REST API that is a Spring Boot servlet application which currently authenticates users with OAuth 1.0 and the password grant. The front-end is an Angular single-page app through which users must log in with their username and password. The API's /oauth/token endpoint then delivers an opaque access token to be used for fetching secured resources that are then displayed within the app.
We'd like to add the possibility to log in using external authentication with OpenID connect, which is a perfect opportunity for switching to OAuth 2.0 and JWT tokens. Our API would then accept JWT tokens it delivered as well as external JWT tokens emitted by accepted issuers.
Reading and validating JWT tokens won't be a problem using Spring security's OAuth Resource Server. However things get complicated with how to make the classic username+password login flow work with JWT tokens.
We thought about delivering JWT access tokens the same way we used to with our old OAuth 1.0 tokens. The thing is, newer OAuth specifications advise against using the password grant, plus it simply isn't supported in the Spring authorization server project we're planning to use. The authorization-code flow w/ PKCE seems like too much for this case as we do not want the back-end API to render a login form but use credentials entered in the existing login form that is part of the single-page app.
I've read a lot about not using OAuth for 1st party login since its primary use is for external authentication, but again, that doesn't apply since we also want 3rd party authentication.
What would be a secure way to implement a Spring boot authorization server that can deliver JWT access tokens to a 1st party client in exchange for a user's credentials, all this using the existing log in page, and given the password grant type no longer being supported?
I thought about implementing a preliminary step that would be a POST request with Basic authentication to a /login endpoint that just returns a 200 HTTP status, then proceeding to the /oauth2/authorize request that would deliver the authorization code immediately without redirecting since my session is authenticated.
I'll be happy to provide more details if needed. Here are the resources I'm using for this project.
What about setting up an authorization-server capable of identity federation?
In such configuration, the authorization-server is responsible for providing with identities, proxying one or more sources (your existing user database for instance, plus maybe Google, Facebook, Github, etc.)
Keycloak does it for instance.
From the client point of view (your Angular app), the authorization-server is used to get:
access-token: put in Authorization header of requests to secured resource-server(s) (can be a JWT or an opaque string, doesn't matter, clients should not try to extract data from access-tokens)
refresh-token: send to authorization-server to renew access-token before it expires
id-token: get user-profile data (email, username, profile picture, etc.)
You should have a look at https://github.com/damienbod/angular-auth-oidc-client for connecting an Angular app to an OIDC authorization-server.
From resource-server point of view, access-tokens are the source ofr setting-up security-context, either by decoding and validating a JWT locally or with token introspection on authorization-server.
Have a look at those tutorials for such resource-servers configuration.
I am currently developing using spring security oauth2.
Currently, the frontend is SPA, and it is developed as react that operates with client side redering.
My rest api has the spring security starters libraries. But I don't know how to use oauth2 flow provided by spring.
So my question is: Can I use spring security as IAM to protect my web and api?
Does spring security have the known oauth2 grants and how use them ?
Implicit grant
Client Credentials Grant
Password grant
Don't use implicit grant
It is not recommended to use the implicit flow (and some servers prohibit this flow entirely) due to the inherent risks of returning access tokens in an HTTP redirect without any confirmation that it has been received by the client.
source: https://oauth.net/2/grant-types/implicit/
With implicit grant, access token is returned immediately without an extra authorization code exchange step. This extra step is usually performed in your backend.
Web > token > Api
SPA frontend and its Rest Api is a very common approach, used since simple startups until big companies. The flow summarized is:
Your users will start the web application.
As they were not signed in before, you web app will show them a login screen (a page provided by the authorization server).
After authenticating, a consent form is showed to the user.
After user consent, the authorization server will send you an authorization code.
The web app will exchange this code for a token.
After getting back this token, the web app store it in the client(browser) and send it as a header when apis needs to be consumed.
Your private rest apis must validate if token of the web app (header) is valid by sending it to one endpoint of the authorization server
If token is valid, your api rest is allowed to respond to the web client. For instance a json with products, employes, some update of customer order details, etc
For this flow to work, you will need:
web spa with a hint of backend. Backend is required because you cannot have a proper user session in static solutions like apache or nginx.
authentication and authorization server: Known as identity and access management (IAM) or some third app which provide you the basic oauth2 endpoints to manage a proper security for your apps.
your apis: foo-api , bar-api, baz-api, etc
spring security
In the minimal scenario in which:
you will have only one web + one rest api, and nothing more in the future (mobiles, iot, etc)
you don't have an authentication/authorization server
you have a mix of functional apis (employee, products, etc) and its security (spring-security) in just one artifact
you don't need user session in your web
you don't need a logout feature
Flow could be reduced to:
Your users will start the web application.
As they were not signed in before, you web app will show them a login screen (a page provided by spring-security).
After authenticating, a consent form is showed to the user.
After user consent, the authorization server will send you an authorization code.
The web app will exchange this code for a token. Since your api is using Spring security, the token generation is covered.
After getting back this token, the web app store it in the client(browser) and send it as a header when apis needs to be consumed.
Your private rest apis must validate if token of the web app (header) is valid by sending it to one endpoint of the authorization server I think the spring security chain filters handle this.
If token is valid, your api rest is allowed to respond to the web client. For instance a json with products, employes, some update of customer order details, etc
Here some samples of token generation and protected endpoints with spring security. I will try to upload a ready to use sample:
https://www.freecodecamp.org/news/how-to-setup-jwt-authorization-and-authentication-in-spring/
IAM
If you will have more applications and complex scenarios in the future, I advice you to choose some open-source iam like:
Glewlwyd,Keycloak,OAuth.io,ORY Hydra,SimpleLogin,SSQ signon,
Commercial services like:
Auth0,Curity Identity Server,FusionAuth,Okta,Red Hat Single Sign-On,cidaas.
Or try to develop a new one using pure spring-security
Lectures
Some recommended answers with more oauth2 details:
https://stackoverflow.com/a/62123945/3957754
https://stackoverflow.com/a/62049409/3957754
https://stackoverflow.com/a/57351168/3957754
https://stackoverflow.com/a/63093136/3957754
https://stackoverflow.com/a/54621986/3957754
https://stackoverflow.com/a/63211493/3957754
I'm currently developing an app in asp.net core 2. However, i'm having issue configuring swagger properly and the authentication layer for the webapi.
In my instance, I have a web api that is configured with jwt. It uses the app id url as the jwt audience. Swagger is configured to run on top of this service and AAD is set up. However, because it's logging in to itself it has the resource configured as the web api client ID. Login successfully works, but the token does not work with the api calls. The main reason is that there is difference in resource/audience. The token is configured with an audience of the client ID and the webapi is conifgured with a jwtaudience of the app ID URL.
It only works if i configure the jwtAudience to the clientID. I doesn't work if i try to update the swagger resource as the app ID URL.
I need the jwtAudience to be configured to the APP ID URL. I can't figure how to do this thou.
Do i need to modify the AAD manifest to give permission to itself?
Any advice appreciated?
Thanks,
Derek
I have an issue with a web api returning HTTP 401 – Unauthorized when I use a Bearer Token to access it from a xamarin client. Either the iOS or UWP fail.
-This is an application that authenticates with Azure Active Directory to allow a user to login
-Once successfully logged in it gets a token that in turn is added to the web api request header
-The web api has its authentication turn on
The issue with azure settings
https://1drv.ms/v/s!ApPhjsvemKJggpR2ax5w4wRJcY7uXQ
the code
https://github.com/wleon12/XamarinForms-AAD-WebAPI.git
I cant seem to figure out what is wrong, appreciate any input or guidance
It depends how you protect the web API.
Normally, when we protect the web API using Azure AD, we will provide the the Audience and Tenant like this code sample. So that when we send the request with the token, the web API will verify the signature of the token and the value we config.
So for the 401 issue, please check the token you acquired with the value you config for the web API project. To check the Audience, Tenant and other values in the token, you can decode it from this site.
I have an angular 2 app, a Web API with OWIN Pipeline (.NET 4.6) and an ADFS 3.0. Every user who uses the angular 2 app needs to be authenticated and authorized via ADFS and if he's already logged in the domain he should be logged in to the Application automatically (Single Sign On)
Something like that:
I read tons of links and code on how to achieve that but I fail to put the pieces together.
As far as I understand ADFS 3.0 only supports OAuth 2 Authorization Code Flow which is either not supported or advised with a JS Application respectively on the Web per se.
I'm not quite sure which it is but the fact is I can't/shouldn't use it.
I understood that therefore I have to implement somekind of Authentication server on my Webserver where my Web API is (maybe IdentityServer 3 or something "homemade").
This lead me to think that I should use ADFS as an external login like google, or facebook which would lead to the following workflow
User requests token
Web API checks if user is already logged in to the domain
Logged in?
forward request to ADFS and verify.
ADFS returns OAuth Token to WebAPI
not logged in?
show login mask to user
forward request to ADFS and verify.
ADFS returns OAuth Token to WebAPI
Web API return OAuth Token to user
Is this even correct or am I completly off?
Anyway I fail to put the pieces to together.
I saw a lot of code which creates JWT Tokens in Web API (but doesn't communicate with ADFS) or communicates with ADFS via WS-Federation.
Additionally ADFS' OAuth 2 implementation seems to a bit special which adds another layer of complexity.
so my question would be:
How can I provide OAuth tokens to the user while authenticating against ADFS?
If you need any additional information I happily provide it
You will need ADFS 2016 which supports Single Page Apps that use Angular.JS. See https://technet.microsoft.com/en-us/windows-server-docs/identity/ad-fs/development/single-page-application-with-ad-fs for the flow and sample code.
You are right that ADFS 2012R2 only support authorization code flow which is only meant for native apps which are public clients to talk to a web api.
Thanks
//Sam (Twitter: #MrADFS)