Web API (under IIS) Windows Authentication with Bearer Token - asp.net-web-api

It's so strange that this simple solution is not yet implemented or is it that I can't Google it ;p) (I'm trying from last 5 days).
My requirements:
Call from Angular App (withCredentials = true) on a URL to see if it is windows user (challenge NTLM). (I may configure this based on what URL user accessing it). If it's a valid Windows user and I find them in DB, I return the Bearer Token.
If Above call returns Unauthorised (401), I show login form to user in my AngularJS (1.6) client. User provides non-windows username and password and when user click Login, from angular service go to another URL (for getting Bearer Token - standard OWIN stuff).
** In any case above, I store Bearer Token in my client for any further API interaction.
I'm not using ASP.NET identity but I have my own DAL to verify user from DB.
I'm going to have my own custom Authorise (inherited) attribute (which will check for Bearer Token only).
I don't want users to enter Windows login on my form and to authenticate them from Active Directory.
I Don't want windows users to click on any separate button to login. (They should just login seamless - with prompt from browser asking them windows login)
I've seen hundreds of posts but nowhere I could see exactly what need. Either the mixed authentication needs to be Cookie based or separate MVC implementation. (Lot's of confusion)
Already referred:
https://techblog.dorogin.com/mixed-windows-forms-authentication-for-ajax-single-page-application-e4aaaac0424a
https://techblog.dorogin.com/mixed-windows-forms-authentication-for-ajax-single-page-application-e4aaaac0424a
https://github.com/MohammadYounes/OWIN-MixedAuth
Don't know if this may help: (but again with cookie) https://github.com/pysco68/Pysco68.Owin.Authentication.Ntlm
Can someone please help?
I may have to give up on this by tomorrow evening :-(

Related

AWS Cognito alternatives to set/comunicate session to different domains using cookies or callbacks or any aws cognito endpoint

currently, I'm working on an application in which we want to offer a single sign-on experience, but let me put you in the context:
We have two different Cognito clients created for the same Cognito pool, both are configured to allow the users to login into two different applications:
App A: mydomain.com
App B: appb.mydomain.com
well, the thing is that when a user uses the hosted UI to log in to the first application, I noticed that the Cognito server creates a cookie called "Cognito" as can see in the image:
Cookie set by the auth server
Then, when a user tries to access the other application appb.mydomain.com, and the application, instead of showing the hosted UI, the user automatically enters the application without going to all the login process again, and this is possible because of the cookie I mentioned (when I delete that cookie, then the user is requested to login again using its credentials).
So, that's nice because the user doesn't need to go through all the login process again. But my situation is the following:
I want to create a login page in mydomain.com with my own customized form and using the Cognito SDK. I already have the backend working, also the frontend. The backend can authenticate users to get the JWT tokens (IDtoken, refresh token, etc.) as you can see in the next image:
Tokens I get when I authenticate a user
But at this point I'm not able to redirect the user to appb.mydomain.com with a valid session, I mean, I have the JWT tokens, and I tried to do the same thing that the hosted UI clients are doing, that is setting a cookie somehow containing the JWT session. But I don't know how to make the application appb.mydomain.com to be able to detect this cookie. But the most important problem is that I really don't know how to construct a valid cookie (like Cognito's) to be detected by mydomain.auth.eu-west-1.amazoncognito.com (this domain is shared for both Hosted UI clients).
I don't know if this approach is feasible, or if there is another approach to send a JWT token to the auth server with a callback to redirect the user to the appb.mydomain.com
without going to all the login process again or something like that.
Do you have any advice on how to implement this kind of SSO Experience? I'm using .Net Core in the backend.

How to invalidate mobile personal access token after backend deletion?

I am using Laravel as my backend together with Sanctum which generates personal access token for mobile users. For my mobile application I am using flutter.
To authenticate users they login with their username/password and get a personal access token in return. This works but requires a user to login every time they open the application again so I did what most tutorials suggest which is saving the token on the mobile device using shared preferences/secure storage.
Now comes the question how do you invalidate a user when you remove their token from the backend? On initial login it appears everything is still fine because like in most tutorial I check for the existence of a token. After that whenever I want to make a request which uses the token I obviously run into problems because it not longer exists on the backend.
Most tutorials/guide suggest saving the token and using that a reference to see if the user is logged in or not but this seems flawed because it gives the false impression you actually have a valid token.
My guess is this can be solved by always performing a heartbeat/ping action to check if the current token is valid and if not send them to the login screen instead of simply checking for the existence of the token.
Thoughts on this?
I can suggest a hack or trick here in every launch of the app you can send a request to an API to check if the user's token is valid or not and if it is valid then you can continue the app otherwise force the user to login and generate new token this way your app will be secure via server / API.
For this, you can store the user's secret token in the database and check it via HTTP API call and send a response from the API accordingly and check the response in app and do the next operation according to the response you get.
I don't know if this is a great way of doing this job but it is a kind of hack/trick to achieve what is needed.
Thanks

Yammer Rest API > Authentication based on server side script (php) without user interaction

My project has the requirement to access the yammer data using the given REST API using server side script(mainly PHP) and not involve a client side login using yammer's OAuth dialog.
I have gone through this document:
https://developer.yammer.com/docs/oauth-2
but this says, we requires user interaction.
What I wanted was can I generate a client_id and client_Secret to further generate access token to make API call out, but in all these processes I only use the authenticated users username and password in my server-side script.
Can anyone suggest a solution or is a client-side interaction required by design?
Thanks in advance!!
You have to have a user authorize the application at least once. This is just the nature of the OAuth implementation and you can't work around it. Having users go through the OAuth flow is considered a best practice.
If you have an OAuth token for a verified admin of Yammer, you can use impersonation to get tokens for end users without them interacting with the OAuth flow.
The below from Microsoft blogs might help you & added source at the end of answer.
Obtain a Verified Admin token for your application in one of the following 2 ways
a. Create the app with a Verified Admin account and then in the app’s Basic Info page, click “Generate a developer token for this application.” Note that you’ll need to use this app’s info in the JS SDK and any subsequent calls.
b. Use the process outlined at https://developer.yammer.com/docs/test-token with a Verified Admin account to get an OAuth token for that VA account. Note that you must use the app info used to generate this token in all future steps.
Obtain the current user’s email address in the server-side script.
Using the VA token obtained in step 1 to authenticate, pass the user’s email address to our Get User by Email Address endpoint documented at https://developer.yammer.com/docs/usersby_emailjsonemailuserdomaincom, and then process the response
a. If the call to the API endpoint returns a 200 OK response, first check the “state” field to make sure the user is “active” and if so, store the “id” field that’s returned and go to step 4
b. If the call returns a 404 or a state other than “active,” direct the user to finish creating and activating their account however you like.
Once you have the user’s ID, you can pass it to our Impersonation endpoint to obtain a pre-authorized OAuth token for that user. This endpoint is documented at https://developer.yammer.com/docs/impersonation and must use the VA token obtained in step 1 to authorize the call, and the consumer_key of your JS SDK app.
You now have an OAuth token for the current user. When generating the code being passed to the browser, have the client side JS SDK code first call yam.platform.getLoginStatus and if there’s no active session and you have a token from step 4, pass that token to yam.platform.setAuthToken($tokenFromStep4, optional_callback_function_if_desired(response)). If you don’t have a valid token, direct the user to finish setting up their Yammer account.
Continue making JS SDK calls as you normally would, without needing the user to authenticate.
Source: https://blogs.technet.microsoft.com/askyammer/2016/11/04/preauthorizing-the-yammer-js-sdk/

Authorise users using MVC identity using PhoneGap

I am using the standard MVC 5 identity membership so users can be authenticated to use features on my site. Apart from login and register, ALL actions require someone to be logged in.
I want to use PhoneGap to take my mobile ready html and turn it into a mobile application. I intend to use ajax to do all calls to my actions.
How do I do this with the html pages not residing on the same server? How can I log someone in, and then allow them to make calls?
Authenticating users from mobile devices is fairly simple with the new MVC 5 identity membership. Essentially, every HTTP request that is made to your server from a device will include a bearer token to authorize that request.
When your Web API method receives the request, it will identify the user making it via the bearer token. This allows you to use the standard Authorize attribute in your Web API controllers that I'm sure you're used to using in MVC controllers. Here is a basic example of this process, but essentially it goes like this:
Request containing username and password is made to your server.
Server verifies the username/password and sends back a bearer token
Make another request(s) to your server to access data or other functionality, and include the bearer token in each request
Assuming you're doing this from a mobile device, some options for storing the token are HTML5 local storage, SQLLite, etc. There is no "logging in" doing it this way - there is only authorization of requests to the server. Of course, the user doesn't know that so it's very easy to simulate a typical logged on experience. Here's a brief example expanding on the one one above:
Create a standard login screen with fields for username and password and a login button
User fills it out, and when they click login you make an AJAX call to your server requesting a bearer token with the user's entered credentials (should be over HTTPS)
Server authenticates the credentials and you get a bearer token back. From the user's perspective, he is now "logged in".
One way to handle the bearer token from here is to store it in SQLlite or local storage so that is readily accessible for you to grab and include in any more requests to the server that you make. You just have to take into account that the token has an expiration (set by you, see that link I posted), and design your app accordingly. You might want to tighten down your security by only keeping the bearer token on the mobile device only so long as the user is using the app. When they're finished, you remove it from the storage on the device and the user must go through the authentication process (i.e "log in") again when they open the app.
Additionally, this video Securing .Net Web APIs is definitely worth watching.

IIS Windows Authentication before Anonymous

I have a website that I would like to allow both Forms and Windows Auth for. My problem is that it seems that when you setup IIS to allow both anonymous (Required for forms auth) and Windows auth that the browser won't send the user's network credentials.
It just uses the anonymous login. Is there any way either in IE8 or IIS to have it try Windows Auth 1st and then fall back to Anonymous?
Thanks for any help.
You can't ask for HTTP authentication (whether that's Basic Authentication or Integrated Windows Authentication) without causing the authentication dialogue box to pop in the case where there are no credentials yet.
So in general for hybrid HTTP-auth+cookie-auth approaches you enable both anonymous and authenticated access for the bulk of the site, but allow only authenticated access to one particular script.
When the user accesses a page without either kind of auth, you spit out a page with a login form for the cookie-based auth, and also a link to the one URL that allows only authenticated access. The user can fill out the form for cookies&forms auth, or hit the link to log in with HTTP auth instead.
If the user follows that link, they will be given a 401 response and must provide HTTP authentication, either through the auth dialog, or potentially automatically using integrated Windows authentication. Once this has happened once, the browser will start submitting the same credentials to every future page, so IIS will decode the credentials to give you the expected REMOTE_USER when your main site scripts are run.
Browsers will only submit the credentials to pages in the same directory as the 401 script, or subdirectories of this. For this reason it is best to put the HTTP-auth-required script in the root, for example as /login.aspx.
However, there are a few browsers that won't automatically submit credentials for further pages, and require every HTTP request to respond 401 first, before sending the request again with credentials. This makes optional-auth and hybrid-auth schemes impossible (as well as making browsing of protected sites much slower!). The only modern browser that does this is Safari. You may not care, as Safari's support for Integrated Windows Authentication has traditionally been shaky anyway, and it can still use the forms+cookies auth type.

Resources