I have an web application made using servlet and I have an seperate API for the web application. I want to secure the API with OAuth so that when we use OAuth, a client certificate is sent instead of credentials to the authorization server for verification and after verification the access should be allowed to the API. Is there any ways to implement this authentication. If possible what are the steps should I do to achieve this?
Client certificate credentials can be used for confidential clients, in either the code flow or the client credentials flow. This type of solution is often used in financial grade setups, where high worth data is involved.
Access tokens issued then contain a cnf claim, so that every API call is bound to the strong credential used at the time of authentication. See the RFC8705 standard for further details.
For a worked end-to-end example that you can run locally, and which covers both the
backend and client behaviours, see this Curity code example. Not all authorization servers support these flows, so check for your provider.
Related
I am implementing notifications within an action. I am able to register users. However, I am not able to figure out how to do the push notification.
As the sample code uses the SDK, I am now stuck at the part "Exchange key for an access token" found in this documentation.
Is it possible to do this without the SDK? using a rest service?
Yes... but...
There is a REST service that does this, in fact, the library ultimately calls it. It is the standard OAuth2 token exchange endpoint at https://www.googleapis.com/oauth2/v4/token. The catch is building the JWT that you can pass to this service. To quote Google's page on the subject:
Although your application can complete these tasks by directly
interacting with the OAuth 2.0 system using HTTP, the mechanics of
server-to-server authentication interactions require applications to
create and cryptographically sign JSON Web Tokens (JWTs), and it's
easy to make serious errors that can have a severe impact on the
security of your application.
For this reason, we strongly encourage you to use libraries, such as
the Google APIs client libraries, that abstract the cryptography away
from your application code.
In short, if you want to do this, you need to:
Create a JSON Web Token (JWT) which includes a header, a claim set, and a signature.
Request an access token from the Google OAuth 2.0 Authorization Server.
Handle the JSON response to get the access token.
Keep track of the lifespan of the access token and, when it expires and you need an access token, repeat steps 1-4.
Details are at
Using OAuth 2.0 for Server to Server Applications
I'm not familiar with C# libraries, however I've been told that Google's C# Client Library seems to support it, and the high level documentation for ServiceAccountCredential appears to be able to generate auth tokens from the credentials.
I've been reading through a bunch of documentation for using OAuth with Azure AD, but am still completely confused about how to properly implement things for my situation. Hopefully someone can steer me in the right direction.
I have created an ASP.NET Web API application that uses the EWS Managed API to access Exchange on behalf of different users. My application exposes endpoints such as /Mailbox/Messages and /Appointments with the intent that some front end web application will eventually use them to retrieve a user's emails and appointments. Currently the endpoints are working using basic http authentication, but I'd like to update them to use OAuth. The application has been registered in my Azure AD instance and I've configured it to require the "Access mailboxes as the signed-in user via Exchange Web Services" API permission.
Since the front end hasn't been implemented yet, I've been trying to test by manually calling the authentication endpoint. This prompts me to log in and provide consent. If I consent, I'm redirected to the callback URL that I provided when I registered the app with the authorization code contained in the query parameters. I'm still not quite sure how I'm supposed to be using this callback, but for the sake of testing I currently have the callback redeem the authorization code for an access token. This is done by calling the AcquireTokenByAuthorizationCode method on an instance of the AuthenticationContext class and providing my application's id and secret. Again, just for the sake of testing I return the access token to the browser. I can then call my aforementioned endpoints (after some modifications) with this access token and get the emails for the user. I'm guessing much of this is not the correct way to be doing things.
Some of my points of confusion:
What should the callback that I registered in Azure AD actually be doing when it gets the authorization code? Is this intended for a different type of application? Perhaps one that isn't just playing the role of a middle man.
I'm trying to make my application somewhat RESTful, so I don't want to have to maintain the access tokens on my end between requests. As such, does it make sense for my endpoints to expect that the access token be provided in the authentication header for each request? If so, does that mean the front end application should be responsible acquiring the access token and passing it to me?
Being completely new to OAuth and Azure, I'm not sure if any other details are pertinent, but I can provide more information as needed.
What you are implementing is this scenario: https://learn.microsoft.com/en-us/azure/active-directory/active-directory-authentication-scenarios#daemon-or-server-application-to-web-api
Here's how it works:
Your client app redirects the user to sign in at the authorization endpoint
Your client app gets back an authorization code (if using the auth code grant flow, there are others)
The client app exchanges the code for an access token for your API app
It will need to provide its client id and secret along with the code and the API's resource URI to get it
The client app calls to your API app, passing the access token in the Authorization header
Your API app then validates the access token, and requests for another access token from Azure AD for the Exchange API
It will pass the access token sent by the client app, along with its client id and secret and the Exchange API's resource URI to Azure AD
Your API app receives an access token so you can call to the Exchange API as the user
And to answer your two questions:
Authorization code flow is not used with APIs, only with apps that have a user signing in, thus the redirect URL is basically never used
Your API can and must expect and authenticate the access token for it to be in every request. But the access token it uses to call the Exchange API can and should be cached on the API's side. This is provided out-of-the-box with ADAL, though the tokens are only in memory.
I'm following the guide and example provided by Microsoft here and I'm able to get the demo working, with the authentication happening in a console app, then making a request to a Web API with the correct token.
I'm looking to use this but the code in the console app would need to move to a Web App. Essentially: external server tries to access secure Web API, providing Azure AD username/password in the Authentication header of a HTTPS request. I pick up these credentials in the first insecure Web API, and attempt to authenticate the credentials against AD, obtaining the token. From here, I would then call the [Authorize]-protected Web API by making a request with the AD token.
At this point I'm using the same code from the example linked above, simply moving the code in the Console app up into the first insecure Web API controller, but I'm having no luck. I read on CloudIdentity that "You can only use those flows from a native client. A confidential client, such as a web site, cannot use direct user credentials.". Is this true? If so, is there another way to achieve my aim? I need to use the credentials as it may be likely that more services would use the API in the future, so each of these would need their own credentials to use that could be managed within Azure.
EDIT: In reading more around this, should I actually be aiming to use Client authentication, creating an "Application" within the Azure AD, and providing the client ID to each external service looking to call the API, to then authenticate with that, rather than credentials?
Yes, your edit is correct. The Resource Owner Password Credentials grant is meant to authenticate users, not applications. Typical use would be from an application that prompts you for username and password and then retrieves a token from Azure AD.
You can use the Client Credentials grant to get a token from Azure AD from a confidential client to call an API without user context. This flow requires that you register the application in Azure AD and generate a key (which will be used as the client secret). You can then use the ADAL library to ge a token from AAD as shown here.
I've been trying to work out if it is possible to authorize communication between a mobile app and my ASP.NET web api service without the user having to authenticate with a username and password. This is important because users of my app don't login at all and never will. All traffic will of course be sent over HTTPS.
This means I can't use OAUTH or BASIC authentication to authenticate the traffic as these require credentials.
So I need some method to securely store some kind of authentication token that is packaged in the app that is only accessed when it needs to communicate to the server and can't be "discovered" by a determined hacker.
This may of course not be possible.
Thanks.
In general it is not possible. Your server should never trust it's clients. Hackers can examine your client app and create equivalent one.
But you can make life of hackers significantly harder, if you:
Use custom cliest sertificat for HTTPS, look here.
Use temporary access keys in http request. Application should request for new temporary access key your server. Part of the key server will send in response and another part will be sent via Cloud Messaging. Combine parts of the key in some non-trivial way.
Obfuscate your app.
I'm investigating creating a WCF REST service for an existing asp.net application to be consumed by various clients including Windows Phone 7, Android, iPhone apps etc.
Creating a simple WCF REST service and consuming it from the above platforms is not a problem and works really well. What I am struggling to get my head around is authorization.
The asp.net application uses the Membership provider to provide authentication and authorization and I'm comfortable in using that API from the REST service.
How do I secure my REST service so that the first call has to be to authenticate (passing the username and password) and following calls know who is 'logged in'. I'm guessing the authenticate method will have to pass back some sort of token to be used in subsequent calls identifying the caller. Is this secure enough as the whole site / service is over SSL?
Any suggestions welcome.
The more restful authentication scheme is to use HTTP Authentication, e.g. Basic or Digest. Since your service is over SSL, Basic should be sufficient. The authentification tokens (login/password) are sent with every request, so that the service can be stateless. Every client library that I'm aware of can deal with basic authentication.
In general the token approach is better then just sending username+password (Basic Authentication) in each request. The problem is to implement it correctly: while Basic Authentication is very easy to implement, and actually it's already implemented by most application and web servers, the token is something you'll need to implement yourself - it must be encrypted, so clients won't understand it, so you'll need some keys management, it also must have some expiration date and may be you'll want some revoke functionality.
In addition, it will make client's life harder: instead of just attaching basic authentication header to each request, client must first go to some authentication point, receive a valid taken and then use the token on the requests. If the token expires, the client will need to go to the authentication point again.
So if you have time and knowledge, and your clients are smart, it's better to use the token approach. Otherwise with SSL, basic authentication should be sufficient.
I've seen an example in the latest Windows Azure toolkit for WP7 that might be helpful for you. It basically uses the Membership Provider, logs in a person (the first time the person installs the app) and then generates a Ticket. It then Encrypts this ticket and sends it back as a TOKEN which is then stored on the phone in the isolated storage. The expiration of the ticket is set to int.MaxValue so that the token remains good for a long period of time.
Now, this token is passed over to the Web Services in the Authorization Header where it is decrypted, the identity of the user is verified and then the web service call is made.
Hoping this helps. I am trying to solve a similar scenario and trust me, there isn't much out there that points us in the right direction...which is a pretty sad state of affairs if you ask me.