java rest service through forbidden 403 error - java

I'm using java to build web api using rest service.
I have add is filter to my web.xml but post request return forbidden 403 error
but when I use get request it works fine.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>POST,GET,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>false</param-value>
</init-param>
</filter>
Here's postman view

When POST is used, the intention from client is to create a resource.
For example,
POST /api/apples/
BODY {color: "green"}
Client issuing this with the intention to create a create apple object at the server side.
GET in other hand is retrieve an object/objects from the server.
For example,
GET /api/apples/
It returns all apples.
If the client posts to an URL and gets 403, it means that your application does not have permission to create object in the server.

add below dependency in your project it's because of the version mismatch of the httpclient. try using version 4.5.3
maven repo link

Related

Get arabic word in ajax json in spring 3 issue

I have web application written in java spring 3, i have used filter
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
but when I get my json using ajax response. It shows '?????'. Is there anybody who have encountered similar issue. I have searched on internet but haven't got any solution.
If you are using mysql db on your back-end ,
Just set Collation as " utf8_general_ci " to save your arabic data, and try it again.

CAS: Invoking a webservice programmatically from within a servlet

I have two applications running on 2 different servers (one on tomcat and other on JBoss). Both these applications are connected to the same CAS server for authentication. Right now this CAS server also resides within the same JBoss.
Say:
App-1 --- is on tomcat and CASified
App-2 --- is on JBoss and CASified
CAS --- is on JBoss
Now that I am invoking an url of App-1 from a browser. The CAS login page comes up and after username/password is provided, the request now successfully enters the servlet of App-1. From this servlet code, I am trying to invoke a webservice that resides inside App-2.
Note: I use axis2 for this webservice and the axis2.war is also CASified
to the same CAS server for authentication.
I could not make this webservice call work no matter what I do. Is there a way to achieve this?
Note: If I call the CAS REST api with a hardcoded username/password, I am
getting the TGT, through which I am able to get the Service Ticket, with
which I am able to invoke that web-service. But I do not want to login again
with a hard-coded username or password. My webservice invocation should
happen with the already logged-in user only.
When you call the web service on App-2 are you getting a session cookie back? This should be the mechanism by which you're continuing to have access without reauthenticating on each call. If you're not getting a cookie back, then there's no way in which to continue access without authenticating each time (i.e. there's no way for the server to remember that it's you and that it should trust the rest of the message).
This is possible by using the CAS Proxy feature.
The link
https://wiki.jasig.org/display/CAS/Proxy+CAS+Walkthrough
helped a bit. But could not understand where to start with.
First take the CAS client jar from http://downloads.jasig.org/cas-clients/ . In my case I took cas-client-core-3.3.3.jar jar. I have included this jar in my application war.
In the web.xml of my application I have included the following 3 CAS Filters.
<!-- CAS Filters -->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://cas-hostname.domainname:port/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://app-hostname.domainname:port</param-value>
</init-param>
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>https://app-hostname.domainname:port/app/ticket</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/app/ticket</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://cas-hostname.domainname:port/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://app-hostname.domainname:port</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!-- filter mappings -->
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/app/*</url-pattern>
<url-pattern>/ticket</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
Note-1: The order of filter mapping should be as mentioned above.
First CAS Validation filter mapping should come, followed by CAS
Authentication Filter and last the CAS HttpServletRequest Wrapper
filter.
Note-2: The URL pattern /ticket which is basically your proxy callback
url need not be mentioned in the last two filters.
Once CAS client jar is included in the web-app and web.xml configured with these filters, then all the http requests go through these filters.
So once your http requests entered your servlet, then you can call the following code snippet to get a proxy ticket:
String proxyTicket = ((AttributePrincipal) req.getUserPrincipal())
.getProxyTicketFor(webservice_url);
req is the HttpServletRequest Object and AttributePrincipal is a class which is present in the cas-client-core-3.3.3.jar
This proxyTicket can then be appended to your web-service's URL as a query string like the following:
https://myother-webservice-app.com/ws/myData?ticket=<proxyTicket>
Once this URL is constructed, then you can make the web-service call programmatically.
Hope this helps.

Why does the basic AUTH box pop up twice in Chrome but not Firefox with spnego SSO

I have a pretty vanilla spnego SSO setup which is authenticating against an Active Directory server. The IE SSO contains the NEGOTIATE header cookie which is authenticating correctly without any prompting the user. Firefox and Chrome do not contain the SSO cookie, and hence fail back to the basic authentication. They do receive the username and password correctly and log in properly.
However, my minor annoyance is that it is prompting once in Firefox, but in Chrome it is prompting for the password twice.
Any ideas on why it could be prompting twice?
Setup below for completeness:
<filter>
<filter-name>SpnegoHttpFilter</filter-name>
<filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
<init-param>
<param-name>spnego.allow.basic</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.localhost</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.unsecure.basic</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.login.client.module</param-name>
<param-value>spnego-client</param-value>
</init-param>
<init-param>
<param-name>spnego.krb5.conf</param-name>
<param-value>xxxxxxxxxxxxx/krb5.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.login.conf</param-name>
<param-value>xxxxxxxxxxxx/login.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.username</param-name>
<param-value>xxxxxxxxxxxxxxxx</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.password</param-name>
<param-value>xxxxxxxxxxxxxxxx</param-value>
</init-param>
<init-param>
<param-name>spnego.login.server.module</param-name>
<param-value>spnego-server</param-value>
</init-param>
<init-param>
<param-name>spnego.prompt.ntlm</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.delegation</param-name>
<param-value>true</param-value>
</init-param>
</filter>
This isn't an explanation why it pops up twice but it is a way to debug it in chrome.
Browse to chrome:net-internals#events and you can see the 401 auth negotiation. The 401 requests and responses do not appear in the network tab of the chrome dev tools, so this is the only clue you can get.
Edit update - it seems that Chrome does not always send the Authorization headers for digest. Either because of pipelining, an auth cache bug, or heuristics for which urls "inherit" the authorization.
From https://groups.google.com/d/msg/chromium-discuss/9ASzOBdBrTQ/wUWFlwFYwaMJ
Since chromium will not pre-emptively send the authorization for
inferred protection space, it will keep entering that loop.
[...]
Support for Digest is likely, but a little sketchier, since the digest
auth model is broken under pipelining (next nonce is controlled by
previous server responses (Authorization-Info).
Because htdigest was causing two login dialogs every page load I switched to basic auth as my site was already using HTTPS for security. Basic and Digest do not define a scheme for which urls the Authorization token needs to be sent and for how long to cache the password or token. So it's slower and less secure than cookies. I'll try to avoid this scheme in the future.

Send specific headers on MIME-type response in Apache Tomcat

I have an Apache Tomcat server running. If I have something like:
webapp/
image1.png
Then, I can simply access it using:
example.com/image1.png
Which is perfect, except that I don't have any control over what headers are being sent. I wish to send specific Expires header for certain MIME-types (like, for image/png). These headers will be static, so I don't really mind if I have to specify this in some XML file and cannot be dynamic.
Is it possible with Apache Tomcat? The other obvious way is to read from the file and output it to the browser with the appropriate headers, but I think that it might be an overkill.
Use Tomcat Filters for applying this headers.
<web-app ...>
...
<filter>
<filter-name>ExpiresFilter</filter-name>
<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
<init-param>
<param-name>ExpiresByType image</param-name>
<param-value>access plus 10 minutes</param-value>
</init-param>
<init-param>
<param-name>ExpiresByType text/css</param-name>
<param-value>access plus 10 minutes</param-value>
</init-param>
<init-param>
<param-name>ExpiresByType application/javascript</param-name>
<param-value>access plus 10 minutes</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>ExpiresFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
...
</web-app>
More Info at Tomcat Filter Documentation
It's possible that you're not using Tomcat 7, but an older version. In my Tomcat 7 installation, I found that filter packaged up in catalina.jar

Logging JSON request and response for jersey

I have a JAVA web application application, which exposes RESTful apis. My requirement is to log all the JSON requests and responses that are handled by the server.
Is there any parameter like -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true for JAX-WS?
I am also exploring AOP approach. What method signature should I add in the AOP pattern?
I am using Tomcat server and jersey for the JAX-RS implementation.
use LoggingFilter. Just add the following to your web.xml:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<!-- Enable Jersey tracing support in Glassfish -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
This worked for me (Jersey 2.x)

Categories