How to implement Token auth for Liferay DXP JSON remote services? - liferay

I need to enable Token-based authentication for Liferay JSON remote services. In short, a guest user should be able to pass in a token while accessing a service, and this token is validated inside an auth pipeline and allows the user to use the service or deny it.
How to implement this in Liferay DXP 7.0?

If it a custom token handling you need to implement, you could use AutoLogin
to have an access to the HTTP request and handle custom tokens part of header or param fields.
Otherwise, it is more common to use oauth2 tokens as liferay has a good build in handling for this (but I am not sure about the 7.0 version).

Related

Verify ADFS Token

I have a JWT retrieved using a usernamemixed endpoint in ADFS 3.0 and now I need to validate this token from a node.js application. How do I achieve this? I know how to validate this token from a WebAPI. I need to do pretty much the same thing in Node.js application. Can I rely just on validating signature of the token(Token Signing Certificate) in node.js, can it be spoofed?
Token validation includes signature checks, but that's not all; you need to check for validation, audience, issuer, etc etc (see http://www.cloudidentity.com/blog/2014/03/03/principles-of-token-validation/).
This is normally achieved by using a validation library that reads the issuer metadata and uses it to validate incoming tokens. If you'd be using ADFS "4.0" you could simply take the Azure AD web API node sample in https://github.com/Azure-Samples/active-directory-node-webapi and point it to ADFS instead. ADFS "3.0" doesn't expose metadata using the openid connect discovery spec, used by that sample, hence the code won't work as-is. However it does provide the same info in its ws-federation metadata doc. If you implement the same scenario using the ASP.NET middleware and capture the network trace, you'll see how you can implement the same check yourself. If you can upgrade your ADFS instance to "4.0", that would be vastly preferable - way less custom code necessary.

How to secure an API when the consumer uses claims authentication

Background
I'm building a .NET MVC enterprise web application that must have the ability to authenticate users from different companies. One of the major requirements was to ensure that users don't need to create and remember new credentials to use the application, instead they should continue to use whatever credentials they use to access applications within their company intranet.
Since the application will be hosted on the extranet and needs to handle authenticating against multiple domains (i.e. multiple Active Directories), we are expecting each client to set up a security token service (AD FS) that the application can interface with to implement claims authentication.
The MVC application will check if the user is authenticated, and if not, start the workflow that ends with the MVC application being given a SAML claim being associated with the user.
Problem
At this point, the user is authenticated and given access to the MVC application. However, the application itself is a modern day web application that uses quite a bit of JavaScript to consume a .NET Web API that handles most of the business logic. My main question is how I can secure this API. I want to make sure the only requests being sent to this server are being sent from a valid source, and that the user consuming the service has permissions to do so.
Current Solutions
There are two approaches I can take to consume the API:
Straight from JavaScript (Preferred solution)
Route the request through the MVC server, which will then forward it to the API.
In order to pick an approach, I first need to find a way to secure the API.
HMAC Authentication
The most straight forward solution I've found is HMAC Authentication - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/. However, this approach requires all API requests to come directly from the MVC server, since the secret key will need to sit on the MVC server.
OAuth 2.0
The second approach I can implement is some flavor of OAuth 2.0. The flavors I'm familiar with can be found here http://alexbilbie.com/guide-to-oauth-2-grants/:
Authorization Code
Implicit
Resource owner credentials
Client credentials
Authorization Code Grant
This is not the approach that I want to take. The MVC application has already received claims for the user - they shouldn't have to do it again just because the API needs the claim. (I have a followup question asking if I can simply pass the claim to the API server)
Implicit Grant
I like the way this approach sounds, since I will be able to execute API requests in the client (i.e. JavaScript code), however it suffers from the same problem as the first approach.
Resource Owner Credentials Grant
This approach is out of the question - I don't want either the MVC application or the API to ever hold onto the user's credentials.
Client Credentials Grant
This approach is the only reasonable OAuth approach listed - however I fail to see a major difference between this approach and HMAC authentication detailed above.
Questions
Have I correctly set up the MVC application's authentication structure? Specifically, in this context is it appropriate to have AD FS handle authentication and respond with SAML tokens representing user claims?
I plan to store user data in the server's session. Can I also store the user's claim in the session, and then somehow send that up to the API for authentication?
If I can pass the claim from the MVC server to the API server, and the API server can correctly authenticate the request, is it safe to pass the claim to the client (browser / JS code) so that consuming the API can bypass the MVC server?
Is the HMAC Authentication approach the best way to go?
Yes, using ADFS or any IdP products as an IdP for your application is a good way to implement SSO. Doing this way help you delegate all the federated access management as well as claim rules to ADFS.
Yes, you can store claims in session and somehow send them to the WebAPI. Please note that if you are using WIF, it already stores claims in Thread.CurrentPrincipal as a ClaimsPrincipal object. Another thing is that I assume you only want to somehow send the claims only, not the whole SAML2 token.
I would say it is as safe as the mechanism you use to protect the token on the client side. Check https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/ and https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side for more details.
I can't say if it is best for you, but it seems to be a viable way, given that you have control over the WebAPI too. However, it also seems that using JWT token would be easier: https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/. Talking about JWT token, you can also ask ADFS to issue it for you: https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/.

Validate LTPA token in nodejs

IS there any way to validate LTPA token previously generated from IBM Tivoli federated Websphere Application Server in my nodejs application.
I have checked "ldapjs", but I could not find something to validate LTPA token.
I have written a small library for this purpose: https://www.npmjs.com/package/ltpa
Once you've extracted your server key you can use the library to validate, and generate LtpaTokens.
There is an Java API related with WSLogin - which allows to validate LTPA. (Technically a re-login here)
But I dont think you can use this with Nodejs.
But my preferred way is to use the BASIC authentication using the URL post from your app.
This requires a provider (Websphere) to expose a URL for you.

Liferay jsonws api: how do I get p_auth from a client?

I'm trying to develop a javascript mobile app that will use a liferay portal jsonws api. I have a username and password. If I try a request using curl with basic auth I can access the resources, but I don't get a token in return, I get a cookie with a sessionid and I have to include username and password in every request. I've no control on the portal. How do I get the p_auth token?
You can use Liferay.authToken to get p_auth from client.
You may go to browser console and type Liferay.authToken to verify that the object is available.
I've used the same object for auth purpose where I was listing down results from JSONW service call. You can save the value in a variable and set anywhere per requirements. I found this the easiest way:
var pAuth = Liferay.authToken;
console.log(pAuth);
Becareful, the parameter p_auth is used to prevent CSRF attack. You can obtain the value with this code:
String pAuth = com.liferay.portal.security.auth.AuthTokenUtil.getToken(request);
TokenUtil is a part of the liferay core, so you must create a hook because the jsp must be in liferay directory, not in a plugin or a portlet because in other classpath you dont have acces to this object.
You can get the authentication token (p_auth) by using Liferay.authToken predefined variable.

WEB API authentication from different platforms

I need to create API application which will be accessed from different platforms (WEB, WPF, Mobile). The API will be hosted on Azure and client will be different websites and desktop/mobile applications. API need to know username to return user-specific information
I have some problems with authentication right now. I used idea from this thread how to do forms authentication to API, but there is a problem there, I have to authenticate each request to API, because the cookie which I created in previous request is not stored to next request.
I am thinking about creating some custom solution there: when login request to API sent with username/password return some kind of token which i will store on client and will pass with each request. In that case I can override AuthorizeAttribute and validate the token.
but I don't believe then I should create custom solution and prefer to find a way to use something Microsoft did for me.
What will be the best way to authenticate to WEB API from different platforms?
In case if I will return token, what is the best way to create it, encode it, expire it...?
There is nothing available out of box currently, to the best of my knowledge. With OWIN, there are things coming up. You can take a look at Katana source code (Microsoft.Owin.Security). For JSON Web Token, Microsoft has the JSON web token handler. More info here. The JSON Web Token Handler can both create and validate JWT. You can use the same library to issue and validate JWT respectively from the token issuer and your web API. Creating all these infrastructure is not easy. Thinktecture identity server and identity model can make these tasks easier for you. Both are open source and you can take a look at the source code in github. Check out this and this. Another good resource is Dominick's blog.

Resources