Apache Camel - Invoking http or rest calls (filtered through Shiro Security) - rest

Need some suggestions to find out if its possible in Camel for the below scenario.
We are trying use Apache Camel for integration testing of a web application. Application has to accessed through rest service calls. Each Application requests is filtered through shiro security. When I make a restful call or a http call to this application, I need to set up the necessary shiro authentication information in the header and make sure the camel request is processed successfully. Is there a way to do this in camel - "invoking a http or rest calls to access the application whose requests are secured by apache shiro" ? I see Camel has a shiro security component which is more like either authorizing camel routes or defining the security for the camel routes and I dont see I can use them for this purpose?
I did try setting up the shiro authentication tokens in the header in different possible ways (For eg: using Exchange's Authentication property) but it doesnt work. Any suggestions please?
UPDATES:
Shiro maintains its own session and looks for userId and his/her Permissions (referred to as Shiro Subject) to make sure its an authenticated and authorized request. Whenever we send a request to a Shiro secured application, it filters the request, validate the request to find out if its authorized to access to application functions and then allow us in.If the user information is not available in the Shiro session, it will take you to the login screen. Our web application has exposed the functionalities as rest services.Is it feasible in Camel to make a call to such an application which is embedded with Apache Shiro security? Basically I am should mock the Shiro subject and set in the HTTP header to make it look like a Shiro Authenticated request.
I tried making http calls with Shiro Authentication token set up in the exchange headers. But its failing. Is this possible in Camel or am I going in the wrong direction? Any suggestion or help in this regard is very much appreciated. Below is a subset of code I have been playing around with.
// wrap it in a Subject
Subject subjectUnderTest = new Subject.Builder(getSecurityManager())
.principals(new SimplePrincipalCollection("Username", "RealmName")).authenticated(true).buildSubject();
MockEndpoint OutEndpoint = getMockEndpoint("mock.out");
OutEndpoint.expectedMessageCount(1);
Endpoint InEndpoint = context.getEndpoint("direct.in");
Map<String, Object> headers = new HashMap<String, Object>();
headers.put(Exchange.HTTP_METHOD, "GET");
headers.put(Exchange.AUTHENTICATION, subjectUnderTest);
template.sendBodyAndHeaders(InEndpoint, "test body", headers);
Thanks Viggy

I think you should use below code to set up user name and password. Set CamelContext with these config.
HttpConfiguration config = new HttpConfiguration();
config.setAuthMethod(AuthMethod.Basic);
config.setAuthUsername("donald");
config.setAuthPassword("duck");
HttpComponent http = context.getComponent("http", HttpComponent.class);
http.setHttpConfiguration(config);

Related

Pass Cognito User Info to HTTP Integration

I've been exploring utilizing Cognito User Pools for authentication and API Gateway to feed client requests with auth tokens. I'd basically like to have a simple react app that utilizes the cognito sdk for authentication. Then use the authentication to make requests via the API Gateway to an express application, hooked up to cognito user pool auth. It would be ideal to have user information available in the express app - seems pretty simple to me.
I've seen many articles and forum posts about how to retrieve Cognito User Info in the context of a lambda function but nothing about how to retrieve Cognito User Info in the context of an HTTP Integration.
Is this possible?
Yes, it is possible, and can be achieved in, at least, two ways:
Proxying requests with original headers
If you enable "Use HTTP Proxy integration" in your HTTP integration, the API Gateway will act as a proxy and forward any headers in the request to the backend (and same from the backend response back to the client). This means that the JWT will reach the express application in the same header the client sent it, where it can be decoded and the claim(s) retrieved.
Using request [and response] data mappings
Another way is to pass the required claim(s) in the Path/QueryString/Headers mappings for the Integration Request, using context.authorizer.claims.{claim} in the mapping, e.g. context.authorizer.claims.email. You can see the documentation on setting up the data mappings and also the mapping reference for more variables that can be used. Please note that for context variables the right syntax to use is without the $ prefix.

Keycloak multiple sessions for the same username

I've recently configured SSO with Keycloak servlet adapter.
The problem is that we have service-to-service communication, which goes with BASIC authentication.
Previously, we were using JAAS authentication, therefore the S2S communication was stateless (no sessions associated).
With the SSO/Keycloak, this is no longer the case. Moreover, each REST request, creates a new Keycloak session.
I tried to find a configuration or an alternative solution without Keycloak customization and coding, but I couldn't.
P.S. Due to backward compatibility, I can't change the REST clients to switch to BEARER or other auth methods.
Anyone having better idea?
I read the point that you cannot change from basic to bearer. But can you switch off your basic authentication altogether from your rest services?
I am saying that because after doing that you may be able to move your authentication logic to a filter.
You can create a Filter that would intercept all requests before they would even reach your Rest Service. This filter handles authentication and based on success proceeds to rest service otherwise returns 401.
Sample code:
public class RequestInterceptor implements Filter
{
if( (performAuth()) )
chain.doFilter(request, response);
else
// set status to HttpServletResponse.SC_SERVICE_UNAVAILABLE
}
// But you will have to find a way to exclude this class from authentication chain.
Try thinking along these lines, you may get some direction.

Access Restful Service which is OWASP CSRFGuard protected from Different Domain

My application has been built using SPRING MVC and I have exposed few Restful URIs. (Working Fine)
e.g - http://example.org/alert/alerts //get list of Alerts for the logged in user.
I have configured the application for Cross Site Request Forgery (CSRF) using OWASP CSRFGuard by following the link - (Working Fine) https://www.owasp.org/index.php/CSRFGuard_3_Configuration#Overview
The Restful services is currently been consumed by the same application's UI without having any issues. (Working Fine)
e.g - A data Grid which is part of the same WebApp is displaying list of Alerts by calling this Restful service (AJAX request)
Issue: When I try to access the same Restful services from a different domain/ Chrome Rest Client, it's doesn't return any data except for 302.
If I set The "unprotected pages" property in csrfguard.properties for the restful URIs, I am able to access the Restful service from RestClient/different domain.
Please suggest if I need to do any other configuration so that the same Restful services which are protected by CSRF can be accessed from a different domain/Chrome rest Client.
1.if you are generating CSRF Token at server side then
provide one get request inside that request validate session and send the created CSRF Token as hidden to client, now remaining request should be POST,PATCH,PUT or DELETE which are getting CSRF Token in every request header.
2. if you are generating CSRF Token at client side then from first request which is authentication or authorization get the value of Token and compare it with every request in your custom filter.

RESTful Authentication via spring with username/passwd and token

I'm developing a mobile app, the server side is REST using Spring 3 MVC.
I was trying to integrate Spring Security with it to secure resources. I've read through a lot of material to get information on how to do it. I understand the architecture, however, when it comes to implementation I am still confused.
I referred a SO question; I have the same requirements. I understand the code, however, I am confused about when the first authenticate request comes in; at that time a token will not be present as the part of the header, so the same filter won't work.
So I was wondering how should I implement it. I was thinking of implementing it as follows:
A separate filter that authenticates user using username password from the request
After authentication the filter sets the authentication info in the context
And another filter that works with tokens for authentication for all API URLs
Is this the correct way to implement it?
No need to add another filter. Whatever the authentication result, the system will try to call handler for corresponding mapping, as you have chain.doFilter() outside if(validate_token).
You must tell Spring security that your request /login MUST NOT BE AUTHENTICATED. You can configure it in xml/java config.

Rest Web service Implementation with ZEND

I need to develop a REST Web Service using ZEND Framework. I am new to this area. I would like to know how can I authenticate user's requests to my web service. Assume I am giving a token to all the people who use my web service. I can ask them to pass the token on every request. But Please suggest me if there and standard / better way to implement authentication for REST web service.
Thank you.
Prasad
I usually include the token in the http header with each request then on the server parse the header and validate the token.
X-Authorization-Token: <some hash value>
It's also completely acceptable to do as you are suggesting and require the user to send the token as part of the GET/POST/PUT/DELETE request as you would with a standard page. I have seen others put the value in a COOKIE as well.