identityServer4 with Login Step-up and MFA - identityserver4

In one of my Projects i need to implement Login Step-up. That means a user can login an application with simple username and password to get some readonly access access on website and API behind it.
If user want to performan any sensetive data operations like "write/update", he need to authenticate via second factor (via SMS code).
second factor login is for maximum 10 minutes valid, if user does not interect the website for 10 minuets, he will be automatically logout from second factor, but he still remain logged in with one factor.
can identityserver4 support this szenario out of the box? or do i need to implement it by my own ?
Here is my solution proposal:
for one factor login, identityserver provide a one factor scope, which client need to understand. it provide a access token which also have limited scope.
when client application need two factor scope, it call identityserver again where user must provide second factor authentication. hence a new token with second factor scope sent back to client. with this token client can call API methodes which need second factor authentication.
second factor authentication token has a validity of 10 minutes
after 10 min token is invalid, but one factor token is still valid as it has long life time.
Questions:
- Can IdentityServer4 offer Login Step-up out-of-box? if no, what are the alternative solutions ?
what is your suggesstion regarding my solution proposal?
Thanks in Advance

What you wrote in the bullet points is basically how I'd see it implemented in IdentityServer4. It's just setting up two different scopes and issuing two separate tokens for the same user. First scope 'readonly', lifetime=24h, acceptable only by safe operations in the application api, second scope 'full' with lifetime=10mins acceptable by all operations. No big problem, it should be perfectly doable with basic IdentityServer4. However, you will have to RT(F)M and configure the scopes, clients, tokens, etc. in the IdentityServer4 config. And also, you'll have to implement the two-token access policies in your app's backend api implementation, and of course client apps will have to be careful about which token they obtain and which token they use for which backend call.. but all of that is more-or-less obvious (and you seem to understand that, judging from that bullet points) so I don't quite see what you'd want by saying "out of the box" or what are you worried about in terms of support for that on the IdentityServer4 side..

Related

Use Microsoft OAuth to authenticate our own operations

We have built a React web application that authenticates users with Microsoft via OAuth ( #azure/msal-browser package). Users are redirected to Microsoft auth page during signin, and then redirected back to our site once authentication has completed successfully. This is all working as expected.
However, we are in a position where we wish to add a custom PIN mechanism to protect some of our workflows. PINs will be encrypted/salted and stored in our own API, along with the existing mapping between Microsoft/Azure users and our own user state/records. In order for users to change/reset their PIN, we want to force them to reauthenticate with Microsoft before changing their PIN. I have not dealt with OAuth2 in a while, and am not entirely certain how this might be possible (since current auth workflow does not involve our server at all).
Ideally, users would navigate to the "Reset PIN" page and initiate the workflow. If possible, authentication would be handled through a pop-up (so as to not lose page state), which I think is possible as per documentation? If this is not possible, even a redirect to the same page with a specific query parameter (to indicate post-authentication) could work. The user would then be able to change/confirm their new PIN. At this point, a request would be sent to our API, including both the PIN and something from Microsoft that would allow our server to validate that the user did indeed just re-authenticate (proving they can change the PIN).
The primary sticking point is that our API must be able to verify that the user has just re-authenticated with Microsoft! One way to think about it would be that if a user gained temporary access to an unlocked authenticated workstation, they should not be able to perform restricted actions (as they do not know the PIN), nor be able to change the PIN (as they do not know the user's credentials). Yes, yes, I know physical access is effectively a compromise to any security, but this is a higher-level requirement...
I am guessing this workflow is possible, but am not certain how it might be possible. Would we use a different authentication workflow for this particular use case? Any pointers on a workflow we could investigate or use for this?
I can give you some info about how this should work. This type of flow can require a high level of extensibility in the authorization server though.
CLIENT REDIRECT
The client can send the OpenID Connect acr_values parameter, indicating the assurance levels it requires. In your case you would send two values.
CUSTOM AUTHENTICATION FACTOR
The user will perform standard authentication first, eg passwords. Then you would implement a custom second factor that uses the user identity and some custom logic to call your custom API.
ACCESS TOKENS
After authentication has completed, the authorization server will issue access tokens to the client. High privilege claims should only be included when strong authentication has been used. Some kind of scripting would be used here, that can read authentication result attributes.
API AUTHORIZATION
APIs should receive short lived access tokens. If it contains the high privilege claim, you know that your PIN requirements have been met.
CAN YOU SIMPLIFY?
It feels suspect to do your own PIN management. Can you outsource this, eg use a second factor of time based one time password (TOTP) instead? Mobile platforms such as the Google authenticator app provide tested solutions.

Authentication for single-page apps

Background
I am looking at the OAuth 2.0 Implicit Grant flow where a user is redirected to an authentication service and a JWT token is sent back a Single Page Application(SPA). The token is stored in a cookie or in local storage and, in the examples i have seen, the application will hide/show certain pages based on whether it can find the token in storage.
Issue
The problem is that in all the examples (official from service providers), i was able to manually add any random but properly formed token to the browser's local storage and got access to the 'secured' pages.
It was explained to me that you cannot validate the token in the SPA because that would require exposing the client secret and that you should validate the token on the API server. This means that you can 'hide' the pages but it is really easy to see them if someone wants to. Having said that you are unlikely to cause any real damage because any data retrieval or actions would need to go through the API server and the token should be validated there.
This is not really a vulnerability but the documentation and examples I have seen do not explicitly cover this nuance and i think that it could lead naive programmers (like myself) to think that some pages are completely secure when it is not strictly the case.
Question
It would be really appreciated if, someone who is better informed than i am, confirm that this is indeed how SPA authentication supposed to work?
I am far from an expert, but I have played a bit in this space. My impression is that you are correct, any showing/hiding of functionality based solely on the presence of a token is easily spoofed. Your SPA could, of course, get into verifying an access token.
But that may just make it a little more challenging to spoof. If someone wants to fake the client into thinking it has a valid token, they can likely manipulate the client-side JS to do that. Unfortunately that's the nature of client-side JS. Much of the code can be manipulated in the browser.
Thus far this is speaking to protecting the user from seeing a UI/UX. Most applications are only beneficial when they have data to populate their UI. That's where the API access token strategy is still sound. The server will verify the token and not give the client any data without it.
So while it's unfortunate that JS can be easily spoofed and manipulated to show things the developer would rather not make visible, this isn't typically a deal-breaker. If you have some awesome UI feature that doesn't need data, and you need to secure access to that UI itself, this model may not be the greatest.

Does authentication differ at all when creating an app with angular?

In a regular web app, when someone logs into the system they simply save an encrypted cookie that gets send on each request and the backend decrypts the cookie and uses the e.g. user_id/guid to lookup the user.
How do things differ when authenticating with a angular app?
Is there anything else to consider or it is basically the same process?
We use more or less the same mechanism.
Access to the application as a whole requires authentication - that is unless you're logged in, you don't get any of the javascript experience at all. This could make the login / login failure much less wizzy for the user, but in our authentication provider it's fine.
Part of our auth mechanism means the list of roles that the user has is a data object available within the browser. The javascript code uses this to decide which buttons / menus etc. are displayed. I checked with our security guy and he said something like "Well, it's a kind of direct object reference issue, but as long as each action is authorised properly, you're probably ok." So it's possible that a user could hack data values and change what they can see, but because of the next bit, they can't break our data (or see stuff that they shouldn't).
Each service call our javascript makes is authenticated and authorised. That is, the javascript call will fail if the auth token is missing or bad, but also, we internally match the auth token with a user and a set of permissions, and only execute that if the user is authorised to do so. (Note that this is good practice whether you're using Angular or not). Also note that this applies to GETs as well as POSTs - we don't want to give them data they should not see.
It gets much trickier if your API is hosted separately from your Angular site.

Securing OAuth clientId/clientSecret in AngularJS application

I know this is probably an age-old question, but...are there any best practices for securing client secrets for performing OAuth2 authentication in AngularJS applications? I've been racking my brain trying to think of a solution to providing truly secure access to an API from modern style web applications (they need not necessarily be AngularJS.) In my experience, adding layers of abstraction and obfuscation really don't do anything to improve security...they just make cracking the security egg more difficult for any prospective hackers (however many of them prefer a good challenge, so all your really doing is just making the hack more fun.)
Aside from the obvious ineffective solutions such as obfuscation and convolution of code and things like that, are there any best practices for securing client secrets in modern day web applications? I know these questions arose with desktop client apps, and I don't believe there was ever a solution beyond "Might as well obfuscate, that'll slow hackers down". Are we in the same boat with web apps? Is there no real solution to this problem?
If there is not a solution...is there even really any point in securing REST APIs with OAuth?
Remember that OAuth is less about protecting against impersonation and more about protecting credentials. 3rd parties authenticated a user's identity for you without exposing the user's credentials. Since Tokens are not credentials, the amount of harm a hacker can do and his window to act are limited.
But OAuth is not inherently more secure for your application than regular username/pwd authentication. And on client-side apps, all your code is available for the world to see! As
you mentioned, client-side encryption is a questionable strategy.
While there aren't established best practices for protecting client interactions, here are some approaches to minimize your exposure:
1) SSL: Silver bullet? Maybe. The more you can use SSL in your site and your requests, the safer your users' requests will be. I honestly believe all privileged requests should be made by encrypted requests.
2) Short Token Life-Span: The shorter the life-span of your Token, the less incentive/advantage of sniffing it.
OAuth 2.0 creates a constant chatter out of authentication by exchanging Authentication Tokens for Refresh Tokens for Authentication Tokens. You, as the developer are now developing a chatty app that does a lot of "what's your token, here's another token, ask me for a token, here's your new token... so what do you want?" ... "oops, time's up, where's your Refresh Token?"
If that sounds like a pain, it kind of is. OAuth 2.0 is designed to make the process easier for you the developer. But the important point is, the shorter the life span of your tokens, the harder for a hacker to maintain a fraudulent identity.
Refresh Token reference
3) Enforce your Domain: Want to give sniffers less chance of abusing the chinks in your armor? Don't allow Cross Domain Requests!
Sure, we often have distributed environments. But if your Facade is on the Client's Domain, your exposure is lessened (word choice questionable).
Force the hacker to use your domain, limit their creativity.
4) Use 3rd party API's for maintaining you access as often as possible: Google and Facebook API's and Services have been unit tested, battle tested, and evolved. The more you can lean on them to maintain your user's Identity, the less work you will do and fewer chances you take.
5) Check IP addresses: Almost anything can be faked, but the hacker must know that IP Address is part of your validation. This is the least assured of all practices, but combined with 1,2, or more, the gaps for hackers to exploit get smaller and the payoffs for effort fade.
6) Use a "Secret" or 2nd parameter: You can pass your users more than tokens. You can pass your own Alter-Token.
Pretend it's an ID data being passed back and forth. Name the param in a non-obvious way. Make it a number (e.g. age, height, address). The important point is, your hacker knows little or nothing of what's being asked for on the other side!
You can throw a serious monkey-wrench by having 3 params that act as security.
7) Don't give error messages to inform the hacker they've been caught. Give timeout msgs rather than "Got You!" If the invaders don't realize the fraud was caught they don't adapt as well.
I can't say it enough -- SSL saves a lot of trouble.
Note: All client Providers I have seen allow access to their API's without exposing Secret. Secret should never be exposed on client.
Any data exposed on client can be gleamed
Any encryption algorithm you use, will be exposed on the client.
I came here looking for the answer to this very question - how to handle the secret/id in an SPA. I came up with my own solution that hides the secret in the server but I wanted to confirm what I was doing was best practice. So since answers avoid this I will explain my flow in hopes that it will help anyone out there.
Our architecture - we have a ruby server as the api server and an express server serving up the Angular app.
Normally all communication is simply done RESTfully thru the api so the node server is just serving static files and not really doing a whole lot.
Since we were at the point of implementing the login/signup flows I came across the - what was new to me - OAuth 2.0 flow of how to handle things.
Before we can make any requests to the server and the server will take us seriously we need to get ourselves the Bearer token. I chose to implement it as a node endpoint thus to hide the client secret inside the node server itself.
So our customer has entered all their juicy data and are redy to become a user in our app they hit the submit button.
The app fires the request to the node server to get ourselves a yummy token that we can use as the Bearer. I chose to pass the client id as a GET request query parameter. First off I had both client id and secret in the node server but it felt like the id could/should be on the, well, client. So I went with this way.
The node server receives the client id thru the GET request and then proceeds to fire the POST to the host(ruby api). Constructing the url + grant type + client id + client secret. Thus hiding the implementation from the world.
The ruby server return a token for us to use which we then return to the client that initialized the signup request.
The SPA now has a Bearer token which we can use in the header of the signup request.
Thus completing our flow and having a hidden cient secret from the world.
Since we have a token with a certain lifespan we also have a request error interceptor that will catch tokens that have expired and thus make a new token request and then refire the failed call.
I have chosen to use on the Angular side of things this lib for users flow.
https://github.com/sahat/satellizer
Its a super handy lib that gets all the boring boilerplate code that has to be written every time we want an app to have authentication thru email/password and also thru oauth....very handy.
So since this is my own interpretation of how to do such things - feedback is kindly requested.

Endpoints API with authentication

My question is : can I use endpoints API or a service with OAuth protocol in general, in sort of that i not need to authenticate the user all time that it send a request to the server but only the first time and for the other times I will use type of token or whatever to use the server directly without check oaut. ALl that in a secure way of course.
the process of check oaut is slowing the response.
Thanks
It depends what you mean by "authenticate the user". OAuth as implemented by Endpoints (and demonstrated with samples) suggests you authenticate the user the first time they use the application (either at install time, or each time they load the app in the browser). From then on, the identity of the user is represented by a token, managed by the client library, and sent along with each request. The server will always verify this token to determine who is making the request, but it does not require user-facing interaction.
If you're asking whether you can use OAuth without continually making the user identify themselves (via an OAuth popup, etc.), yes, this is the way it works by default in the samples.
If you're asking whether you can use OAuth without verifying the tokens on each request, you could, but it's not worth doing, because it doesn't get you a lot from a security perspective or save you much performance-wise.

Resources