I have an application which exposes a RESTful API using RESTEasy. The user needs to authenticate using HTTP-Basic before any method can be invoked.
However, I want to add a method to the RESTful API which any user can invoke without authenticating. How do I do that? Is there some JAX-RS/RESTEasy annotation that I can add to the method declaration to indicate that authentication is optional for that method.
Thanks.
In your web.xml exclude REST paths, that does not need authentication
<security-constraint>
<web-resource-collection>
<web-resource-name>All Access</web-resource-name>
<url-pattern>/unchecked/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
Then your REST resource that does not need authentication should be something like
#Path("/unchecked")
public class NoAuthResource{
}
Related
I am a computer science student and have used Quarkus for several projects in the past year.
I recently received a new project where I have to create a rest API. Because I have to do a lot in a short time, I use Quarkus to easily do the job with RESTEasy for my web services.
But this API has to authenticate the user by using Apereo with protocols CAS or SAML2.
Moreover I have no experience in using Java security plugins.
I also searched about how to deal with that by using keycloak, Apereo Jboss client, Apero Spring boot client or by having a service along with Quarkus like a Tomcat that will do the authentication job. But I don't know which one would be the best and even which one would actually work.
Do you have any experience around that ?
Or what could I use to make my Quarkus API work with Apereo ?
Thank you very much for your time and help,
Best regards,
Thomas
Sorry for being late to the party, but I actually did a quarkus - apareo cas integration.
Basically I added quarkus-undertow extension to be able to use src/main/resources/META-INF/web.xml.
Also I used org.jasig.cas.client:cas-client-core:3.6.1 to have the cas filters.
And my web.xml contains something like this:
<context-param>
<param-name>serverName</param-name>
<param-value>${cas.redirect.url}</param-value>
</context-param>
<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>${cas.login.url}</param-value>
</init-param>
<init-param>
<param-name>ignorePattern</param-name>
<param-value>/proxy/</param-value>
</init-param>
<init-param>
<param-name>ignoreUrlPatternType</param-name>
<param-value>CONTAINS</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<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>${cas.base.url}</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Saml integration is similar, just use the SAML filters.
For more information on configuration options, please see java-cas-client
Off topic, why do you need to authenticate a API via CAS? It redirects you to that CAS login window, then it redirects you back. you cant use this API via postman or curl. Also an API doesn't store any session about the user, so this redirect dance happens every time. This is not how API's are secured. Web pages or web applications yes, but not API's.
I want to test my wcf service endpoint using SOAP UI tool which is built in wsHttpBinding along with x509certificate authentication. It supports for basicHttpBinding and working properly but giving an error for wsHttpBinding. Any help would be appreciated. I'm getting below error message in response.
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>uuid:81f1ec47-0bd4-4dd0-b958-648ee934be24</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">An error occurred when verifying security for the message.</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
We are capable of testing the WCF service in SOAPUI if WCF service is created by Wshttpbinding and the required client credential is a certificate.
Please refer to the reply I wrote several days ago.
Test WCF with Mutual Certificate Authentication using SOAPUI
Merely based on the security error. I could not infer that the code design on the server-side. I would like that you could post more details of the security binding configured on the server-side and the client's credential type so that I could make an example.
Besides, here are some links, wish it is useful to you.
WCF wsHttpBinding in SoapUI
https://www.soapui.org/docs/functional-testing/sending-https-requests.html
Feel free to let me know if there is anything I can help with.
After looking around the forums and the internet in general, I was unable to find anything that answered my problem, so I have resorted to placing my question here.
Firstly, sorry if this has already had an answer supplied.
My problem is this. I have an existing C# WCF service hosting in IIS and secured by an SSL. This is working code and is currently in our Live, UAT, Test and Development environments.
I have been asked to use SoapUI for testing firstly on existing services and any new services that we are about to build.
So far, I have created the project by supplying the WDSL, setup the keystore with the SSL cert, created an outgoing and incoming WS-Sec config.
When in the request, I have created a basic authorization using the defined outgoing and incoming configs created above.
After clicking on the submit button, I get the following response.
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" ns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>uuid:89964641-b66d-42c7-b40a-bdd3b7acdddf</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-GB">An error occurred when verifying security for the message.</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
I did see an article that inferred that I should switch the 'Enable WS_A addressing' switch off. I did this, but this just caused the submit request to timeout.
I have checked that the service is running by viewing the WSDL from the IIS server and also using the application to call the service and all is OK.
I am sure that I missed a simple step, so would be grateful for any help.
Thanks
After looking around, I have started to use WCF Storm which does appear to work with WCF using SSL.
General notes
We're using IdentityServer3 and have been very happy with it so far.
We've gotten to secure MVC and ASP.NET Web API applications very easily with the help of both MS and Thinktecture OWIN middlewares.
The client we're working for still has a lot of SOAP WCF services, and this is where we're getting stuck.
The Setup
I'm not gonna lie, I'm far from being experienced with WCF, I've only used it for very basic scenarios - understand basicHttpBinding, no transport nor message security.
This is what I want to achieve:
A client gets a JWT access token from IdentityServer
Somehow the token ends up in the SOAP message headers
WCF reads and validates the token
WCF inspects the claims and performs authorization based on some criterion
I can't get the third step working.
The server setup
I'm using a ws2007FederationHttpBinding with TransportWithMessageCredential security mode. The message contains a BearerKey and the token is of type urn:ietf:params:oauth:token-type:jwt
The service uses the WIF identity pipeline, in which I added the JwtSecurityTokenHandler from the System.IdentityModel.Tokens.Jwt NuGet package
The client setup
The JWT token issued by the STS is wrapped in a BinarySecurityToken XML element, itself wrapped in a GenericXmlSecurityElement
This token is used as a parameter of the CreateChannelWithIssuedToken of the ChannelFactory
What happens
The token is found in the SOAP header and passed on to the JwtSecurityTokenHandler.
But then an exception is thrown:
System.ServiceModel.Security.MessageSecurityException: Message security verification failed. ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Xml.XmlBufferReader.GetChars(Int32 offset, Int32 length, Char[] chars)
at System.Xml.XmlBufferReader.GetString(Int32 offset, Int32 length)
at System.Xml.StringHandle.GetString()
at System.Xml.XmlBaseReader.ReadEndElement()
at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
--- End of inner exception stack trace ---
After JustDecompiling, it looks like there's an error when further reading the XML elements in the SOAP header. What's strange is that the token is the last element. Here's what the whole message looks like:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService/GetListOfStrings</a:Action>
<a:MessageID>urn:uuid:5c22d4e2-f9b8-451a-b4ca-a844f41f7231</a:MessageID>
<ActivityId CorrelationId="554fc496-7c47-4063-9539-d25606f186b0" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">1213dcd7-55b7-4153-8a6d-92e0922f76dd</ActivityId>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo90CpMlUwLBOmEPkZ5C8fRQAAAAAVWkkf2rJS0qImBv+Yx1recUXdbBLjThDkAMkwfW3/2AACQAA</VsDebuggerCausalityData>
<a:To s:mustUnderstand="1">https://localhost.fiddler:44322/Service.svc</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-05-21T06:41:45.362Z</u:Created>
<u:Expires>2015-05-21T06:46:45.362Z</u:Expires>
</u:Timestamp>
<wsse:BinarySecurityToken ValueType="urn:ietf:params:oauth:token-type:jwt" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><!-- Removed --></wsse:BinarySecurityToken>
</o:Security>
</s:Header>
<s:Body>
<GetListOfStrings xmlns="http://tempuri.org/" />
</s:Body>
</s:Envelope>
Doesn't look like there's something malformed or anything. From the stack trace, the exception must be thrown when reading the </o:Security> end element since the token was properly read and handled.
Repro
I forked the samples repo so you can have a look if you feel like it.
Here are the relevant projets:
SelfHost (Minimal) in the sources folder. This is the STS
In the Clients solution, the WCF service is in the APIs folder
In the Clients solution, the WCF client is the Console Client Credentials With Wcf project
Best way to fire it up is to start the STS first, then Right click -> Debug -> Start new instance on the WCF service, then the same on the WCF client.
Thanks in advance!
I didn't get to solve this problem but Dominick Baier, one of the developers of IdentityServer, found a workaround.
He thinks the exception comes from a bug in WCF or an incompatibility between WCF and the JwtSecurityTokenHandler. Since he considers WCF done, he doesn't expect someone to take a look at it.
His solution is to wrap the JWT token in a SAML token. Then, by subclassing SamlSecurityTokenHandler, get it back and validate it against an instance of JwtSecurityTokenHandler.
Here are the links:
Dominick's blog post
Samples repo on GitHub where he put the code
Specific commit on GitHub
Everybody have fun, now :-)
I am new to jax rs implementation.
I had created RESTFUL application contains the web services using jax rs.
But I want to provide the authentication and authorization to some of the web services.
I am unable to configure the web.xml for the authentication.
Thanks in advance
You can use container-level authentication. For instance, in Apache Tomcat, you can configure HTTP-based authentication (e.g. BASIC, DIGEST, or even FORM-based though the latter does not make sense for APIs).
To configure HTTP BASIC authentication as an example you need to:
define users in a user store and connect Tomcat to it. By default Tomcat provides you with a tomcat-users.xml file which you can use to define users. You could also configure Tomcat to use LDAP as a source
update your web.xml file to add the security-constraint element
update your web.xml to add the login-config element
update your web.xml to add the security-role element
Here's an example snippet:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>basic-user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>basic-user</role-name>
</security-role>
Note that there is a great answer already available here too: Easy way for Authentication and Authorization with JAX-RS Jersey