Hello,
I'm testing an app prototype that authenticates through CAS 7.0.6.
The architecture is as follows:
-Frontend in Vue, with a function that calls a backend API in order to authenticate.
(for example, hostname would be frontend.mydomain).
Source code for authenticating is as follows:
import axios from 'axios';
export default
{
async authenticate() {
try {
const response = await axios.get('https://backend.mydomain/api/authenticate.php', {
withCredentials: true
});
return response.data;
} catch (error) {
console.error('Error
during authentication:',
error);
return null;
}
}
};
-Backend in PHP, using phpCAS.
(For example, hostname would be backend.mydomain).
Source code is as follows:
<?php
header('Access-Control-Allow-Origin: https://frontend.mydomain);
header('Access-Control-Allow-Credentials:
true');
header('Access-Control-Allow-Methods: GET,
POST, OPTIONS');
header('Content-Type: application/json');
require_once '../vendor/autoload.php';
// OPTIONS requests handling
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS')
{
exit; // Just in case, not needed.
}
phpCAS::client(CAS_VERSION_2_0, 'cas-server.mydomain2', 443, '/cas',
'https://frontend.mydomain');
phpCAS::setNoCasServerValidation();
// Check if user is
authenticated
if (phpCAS::isAuthenticated()) {
$user = phpCAS::getUser();
$attributes = phpCAS::getAttributes();
// Returns
user data in JSON format
echo json_encode([
'authenticated' => true,
'user' => $user,
'attributes' => $attributes
]);
} else {
// Redirects
user to CAS login page
phpCAS::forceAuthentication();
}
?>
-CAS Server 7.0.6, with hostname cas-server.mydomain2.
Relevant CAS configuration:
/etc/cas/config/cas.properties (excerpt):
cas.http-web-request.cors.enabled=true
cas.http-web-request.header.enabled=true
cas.http-web-request.cors.allow-credentials=false
cas.http-web-request.cors.allow-origins=*
cas.http-web-request.cors.allow-methods=*
cas.http-web-request.cors.allow-headers=*
cas.http-web-request.cors.max-age=3600
I also tried cas.http-web-request.cors.allow-credentials=true and cas.http-web-request.cors.allow-origin-patterns=https://frontend.mydomain,https://cas-server.mydomain2 with no luck.
/etc/cas/services/frontend-9900018.json:
{
"id" : 9900018,
"name" :
"Frontend",
"description" :
"Frontend",
"serviceId" :
"^https:\\/\\/frontend[.]mydomain(?:\\/?|\\/.*)",
"@class" :
"org.apereo.cas.services.CasRegisteredService",
"evaluationOrder" : 10,
"logoutType" :
"BACK_CHANNEL",
"logoutUrl" :
"https://login.microsoftonline.com/xxxxx-redacted-for-obfuscation-xxxxx/saml2"
"accessStrategy" : {
"@class" :
"org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
"delegatedAuthenticationPolicy"
: {
"@class" :
"org.apereo.cas.services.DefaultRegisteredServiceDelegatedAuthenticationPolicy",
"allowedProviders" : [ "java.util.ArrayList", [
"My-SAML-Provider" ] ],
"exclusive": true
}
}
"attributeReleasePolicy"
: {
"@class" :
"org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
"allowedAttributes" : {
"@class" : "java.util.TreeMap",
"userid" : "groovy { return
attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name']}"
"displayname" : "groovy { return
attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/displayname']}"
"roles" : "groovy { return
attributes['http://schemas.microsoft.com/ws/2008/06/identity/claims/role']}"
}
}
"properties" : {
"@class" : "java.util.HashMap",
"corsAllowedOrigins" : {
"@class" :
"org.apereo.cas.services.DefaultRegisteredServiceProperty",
"values" : [ "java.util.HashSet", [ "https://frontend.mydomain" ] ]
}
"corsAllowCredentials" : {
"@class" :
"org.apereo.cas.services.DefaultRegisteredServiceProperty",
"values" : [ "java.util.HashSet", [ "true" ] ]
}
}
}
Of course, SAML configuration is right (verified in other services with traditional PHP that renders pages).
When I go to URL https://frontend.mydomain in browser, I can see in dev tools the following error:
"Access to XMLHttpRequest at 'frontend.mydomain/:1 https://cas-server.mydomain2/cas/login?service=https%3A%2F%2Ffrontend.mydomain%2Fapi%2Fauthenticate.php' (redirected from 'https://backend.mydomain/api/authenticate.php') from origin 'https://frontend.mydomain' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
"GET https://cas-server.mydomain2/cas/login?service=https%3A%2F%2Ffrontend.mydomain%2Fapi%2Fauthenticate.php net::ERR_FAILED 403 (Forbidden)
Looking at the request headers of the failing request, I can see "Origin: null" and I think this could be the culprit.
Why Axios/browser is sending the GET request to CAS server with "Origin: null" header?
Anybody tried this architecture an faced the same issues?
Thanks in advance.
Best regards,
Oscar Alonso