Modifing redirect URL in CAS - deployment

Is it possible to modify redirect URL in CAS server based on user? Lets say i have 2 versions of application (a.com and b.com). User tries to login into a.com , gets redirected to CAS server, if login is successful i want to redirect him to b.com (with authentication completed). Application are running on Wildfly servers (if that matters). Basically i want some users to have access to new version of my app which is deployed on another server without them knowing that they use it (i think it's called A/B testing). Is there a way to achieve it with CAS server or maybe there are some other tools?

In case it's not too late, this is possible simply with the authentication and validation filters.
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>a.com/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>a.com</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>tolerance</param-name>
<param-value>30000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
You can filter users filter-mapping.

Related

Keycloak OIDC Filter redirect_uri is always http

My application was developed using wicket and integrated with keycloak 10.0.2.
I have an issue with the redirect_uri, it is always in http (like https://id.dev.subok.com/auth/realms/subok/protocol/openid-connect/auth? ... &redirect_uri=http%3A%2F%2Ftest.subok.com%2F ....
To elaborate:
When I try to access my app via https://test.subok.com, I am expecting that the redirect_uri will be https%3A%2F%2Ftest.subok.com%2F but it was http%3A%2F%2Ftest.subok.com%2F. The redirect_uri is always http even if I use http or https.
The way I integrate Keycloak to my application is via servlet filter:
POM
...
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-servlet-filter-adapter</artifactId>
<version>10.0.2</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
<version>10.0.2</version>
</dependency>
...
web.xml
...
<filter>
<filter-name>keycloak</filter-name>
<filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class>
<init-param>
<param-name>keycloak.config.skipPattern</param-name>
<param-value>/((error-page.html)|(access-denied-page.html))</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>keycloak</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
Is there a way to override the value of generated redirect_uri? Specifically to use https if the request is https and http if the request is http. Or just use https redirect_url for both http and https request?

BaseX: Public REST API without authentication

Is it possible to create a public REST API in BaseX, so that clients do not need to authenticate at all?
This public API should be read-only. What I already have done is creating a user called HTTPGuest, which has read access to certain databases.
Then I have tried basexhttp -UHTTPGuest. But the API still wants to have credentials via Basic Authentication.
You can provide default credentials by modifying the web.xml file, which is usually located at ~/BaseXWeb/WEB-INF/web.xml. This file contains following block>
<!-- REST Service (can be deactivated by removing this entry) -->
<servlet>
<servlet-name>REST</servlet-name>
<servlet-class>org.basex.http.rest.RESTServlet</servlet-class>
<!-- service-specific credentials
<init-param>
<param-name>org.basex.user</param-name>
<param-value/>
</init-param>
<init-param>
<param-name>org.basex.password</param-name>
<param-value/>
</init-param>
-->
</servlet>
<servlet-mapping>
<servlet-name>REST</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Here, uncomment the <init-param/> subtree and add the user/passphrase combination to the <param-value/> elements, for example
<!-- REST Service (can be deactivated by removing this entry) -->
<servlet>
<servlet-name>REST</servlet-name>
<servlet-class>org.basex.http.rest.RESTServlet</servlet-class>
<init-param>
<param-name>org.basex.user</param-name>
<param-value>HTTPGuest</param-value>
</init-param>
<init-param>
<param-name>org.basex.password</param-name>
<param-value>super-secret-passphrase</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>REST</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

CORS issues while accessing https REST end point

I want to consume a REST resource available at http://localhost:9080/StudentWeb/MyRest-rest/services/students/
from my AngularJS app, and the REST application is deployed in Websphere Appliation Server with following deployment descriptor (web.xml). And application is working perfect with this configuration, with users in RegisteredUsers role.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>MyRestApplicationServicesWeb</display-name>
<servlet>
<description>
JAX-RS Tools Generated - Do not modify</description>
<servlet-name>MyRestRest</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.myrest.student.rest.StudentApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>MyRestRest</servlet-name>
<url-pattern>/MyRest-rest/*</url-pattern>
</servlet-mapping>
<security-role>
<description>RegisteredUsers</description>
<role-name>RegisteredUsers</role-name>
</security-role>
<security-constraint>
<display-name>Area for authenticated users</display-name>
<web-resource-collection>
<web-resource-name>Protected Resources</web-resource-name>
<url-pattern>/MyRest-rest/services/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>RegisteredUsers</role-name>
</auth-constraint>
</security-constraint>
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.myrest.student.filter.StudentCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/MyRest-rest/*</url-pattern>
</filter-mapping>
</web-app>
I want secure the data flow between the AngularJS app and WAS REST endpoint, by adding converting REST API to https. For that added,
<user-data-constraint>
<description>Redirects http requests to https</description>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
in the security-constraint tag.
And please find the CORS filter added,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Inside Filter");
((HttpServletResponse) response).addHeader("Access-Control-Allow-Origin", "*");
((HttpServletResponse) response).addHeader("Access-Control-Allow-Credentials", "true");
((HttpServletResponse) response).addHeader("Access-Control-Allow-Method", "GET, POST, PUT, DELETE, OPTIONS");
((HttpServletResponse) response).addHeader("Content-Type", "application/json");
((HttpServletResponse) response).addHeader("Access-Control-Allow-Headers", "Content-Type");
String accessControlReqHeader = ((HttpServletRequest) request).getHeader("Access-Control-Request-Headers");
System.out.println(accessControlReqHeader);
if (((HttpServletRequest) request).getMethod().equalsIgnoreCase("OPTIONS")) {
((HttpServletResponse) response).addHeader("Access-Control-Allow-Headers", accessControlReqHeader);
} else {
chain.doFilter(request, response);
}
}
But now getting error on AngularJS app as follows,
XMLHttpRequest cannot load http://localhost:9080/StudentWeb/MyRest-rest/services/students/12341234. The request was redirected to 'https://localhost:9443/StudentWeb/MyRest-rest/services/students/12341234', which is disallowed for cross-origin requests that require preflight.
I can see this as a CORS issue for https. How can I get around with this issue.
Here's your problem, or at least one of them.
((HttpServletResponse) response).addHeader("Access-Control-Allow-Origin", "*");
You can't use the wildcard when sending credentials with a CORS request. Instead explicitly list the origin. If you will have many, inspect the origin header from the client and if your server decides to serve content to that client then return the content of the request origin header as the value of Access-Control-Allow-Origin response header.

Tomcat7 REST Service with Basic Authentification XMLHttpRequest

I'm just setting up a small TestScenario. I'm exposing a REST Service on Tomcat 7 with Jersey. The service is called by another Javascript/HTML5 Application via XMLHttpRequest.
For testing I just run the REST Service inside my eclipse installation with Tomcat.
Calling the REST Service from JavaScript works fine without any authentication setup.
Now I'm trying to add Basic Authentication mechanism to my REST Services. In the web.xml of my web project i added
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ImageLinksServices</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.xxx.xxx.services</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<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>GET,POST,HEAD,OPTIONS,PUT,DELETE</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>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>tomcat1</role-name>
</auth-constraint>
<user-data-constraint>
<!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
Calling the REST URL from Browser works fine. He asks for user and password then the Response of the REST service is displayed.
But when i try to call it from a Javascript with the following snipplet i receive always a 403 error and a warning that
OPTIONS http://localhost:10080/xxxx/rest/fileupload No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access
Code Snipplet i'm currently using:
xhr.open('POST', url, true);
//xhr.open("POST", url, true, "user1", "tomcat1");
xhr.setRequestHeader("Authorization","Basic "+ btoa("user1:tomcat1"));
xhr.withCredentials = "true";
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
var jsonResponse = JSON.parse(xhr.responseText);
What I'm doing wrong ? I'm totally confused why now after adding authentication the Browser complains about No Access Control Header is present. Before adding authentication to the service the call works also with CORS.
What I can see from the HTTP Request that the Basic Authentication Header seems to be set correctly.
Request URL:http://localhost:10080/xxx/rest/fileupload
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:authorization, content-type
Access-Control-Request-Method:POST
Authorization:Basic dXNlcjE6dG9tY2F0MQ==
Connection:keep-alive
Host:localhost:10080
Origin:http://localhost:63342
Referer:http://localhost:63342/xxx/html/index.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Response Headersview source
Content-Length:0
Content-Type:text/plain
Date:Thu, 05 Dec 2013 12:58:46 GMT
Server:Apache-Coyote/1.1
Can anyone help me to understand what I'm doing wrong. I confused if a Tmocat configruation is mssing or my Javascript is wrong.
I don't know if you managed to resolve your issue, but I ran into the same problem and debugged through the org.apache.catalina.filters.CorsFilter to figure out why the request was being forbidden.
According to the W3 CORS Spec Section 6.2 Preflight Requests, the preflight must reject the request if any header submitted does not match the allowed headers.
The default configuration for the CorsFilter cors.allowed.headers (as is yours) does not include the Authorization header that is submitted with the request.
I updated the cors.allowed.headers filter setting to accept the authorization header and the preflight request is now successful.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<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,Authorization</param-value>
</init-param>
</filter>

RESTEasy Asynchronous Job Service + Spring MVC?

I am using the RESTEasy integration with Spring MVC as described here in section "39.2. Spring MVC Integration"
http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/RESTEasy_Spring_Integration.html
I'd like to experiment with RESTEasy's implementation of the "async job service" as described here:
http://docs.jboss.org/resteasy/docs/2.3.4.Final/userguide/html/async_job_service.html
Reading the doc, my assumption is that RESTEasy will intercept the request and respond with a HTTP 202 and do the job queueing and tracking and create the .../async/jobs endpoint. So I modified my web.xml as described in the documention. Here's what it looks like:
<web-app>
<context-param>
<param-name>resteasy.async.job.service.enabled</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.async.job.service.base.path</param-name>
<param-value>/asynch/jobs</param-value>
</context-param>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I tried to test whether this works by making a call to one of my REST services like this (running under Tomcat 6):
POST http://localhost:8080/myservice?async=true
According to the documentation this service is supposed to return a HTTP 202 but it returned the normal HTTP 200 as if I had called without the async=true query param.
I didn't change anything else with my services. Am I missing something?
Btw, here's what the service annotation looks like:
#Controller
#Path("/")
public class MyServices {
#POST
#Produces({MediaType.APPLICATION_XML})
#Path("myservice")
public Response createMyResource(#Context UriInfo uri, myResource) {
// create the resource
// construct and return a OK Response
}
}
Has anyone tried this successfully? If not, do you have another easy to use alternative for making async calls to RESTEasy RESTful services (that also works with Spring running under tomcat)
Thanks.
Try with asynch=true not async=true