AccessDeniedException in log before rewriting - symfony

In 4.1 when a user want to access in page with security (#Security("has_role('ROLE_ADMIN')" for example), the user will be redirect in the login page. It's working. I have no error 500.
But in my log /var/log/prod.log i have some error :
[2018-06-06 09:30:47] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Security\Core\Exception\AccessDeniedException: "Access Denied." at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php line 68 {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php:68)"} []
[2018-06-06 09:30:47] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php:68)"} []
[2018-06-06 09:30:47] security.DEBUG: Calling Authentication entry point. [] []
I don't understand why I have critical error.

Symfony Framework defines a Symfony\Component\HttpKernel\EventListener\ExceptionListener that subscribes to KernelEvents::EXCEPTION with very high priority of 2048 for method logKernelException (see https://github.com/symfony/http-kernel/blob/master/EventListener/ExceptionListener.php#L93) :
public static function getSubscribedEvents()
{
return array(
KernelEvents::EXCEPTION => array(
array('logKernelException', 2048),
array('onKernelException', -128),
),
);
}
So thrown AccessDeniedException is firstly handled by this logKernelException method that logs it with CRITICAL level (see https://github.com/symfony/http-kernel/blob/master/EventListener/ExceptionListener.php#L109) :
protected function logException(\Exception $exception, $message)
{
if (null !== $this->logger) {
if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
$this->logger->critical($message, array('exception' => $exception));
} else {
$this->logger->error($message, array('exception' => $exception));
}
}
}
At this step, AccessDeniedException has been logged on the request channel. It's totally relevant from the request scope : original request has failed because no authentication had been performed...
Then, Symfony\Component\Security\Http\Firewall\ExceptionListener, listening KernelEvents::EXCEPTION but handling only authentication related ones (see https://github.com/symfony/security/blob/master/Http/Firewall/ExceptionListener.php#L87) goes on duties in order to redirect to authentication start point...

Related

How to Block Http Methods in ASP.NET

We have a requirement of disabling the HTTP methods besides POST, GET and Head in an ASPNET Core Web application due as a part of security fixes. How can we disable the HTTP OPTIONS method in ASP.Net core API?
Allowed 3 methods which are POST,GET and Head.
How to block all the others method which I didn't use in middleware like DELETE,TRACE,PATCH and etc.
Needs to return Error Code 405 = Method Not Allowed . Currently it throws the error 500 which is Internal Server Error
my code right now .
app.Use(async (context, next) =>
{
if (context.Request.Method=="TRACE")
{
context.Response.StatusCode = 405;
return;
}
await next.Invoke();
});
How to Block Http Methods in ASP.NET
You could try as below:
app.MapWhen(x => x.Request.Method == "somemethod",
y => y.Use(async(context,next)=>
{
context.Response.StatusCode = 405;
await context.Response.WriteAsync("Method Not Allowed");
}
));
The Result:

Firebase Cloud Functions - Throw Auth Error

Is it possible to throw an Auth Error from HTTPs callble functions?
I mean, instead of this
if (err.code === "auth/email-already-exists") {
throw new functions.https.HttpsError(
"invalid-argument",
"The email address is already in use by other account"
);
}
something like
exports.signUp = functions
.region("us-central1")
.runWith({ memory: "2GB", timeoutSeconds: 120 })
.https.onCall(async (data, context) => {
...
if (err.code === "auth/email-already-exists") {
throw err;
}
...
}
Callable Functions should return an instance of HttpsError which requires gRPC error codes so the details of the error are properly transmitted to calling clients. If you throw a different error type, the client will only see a HttpsError with the code and message "internal" - no specifics will be sent to the client for safety.
If you want to pass through the error code of a Firebase Error, you can do so using the third argument. Also consider using "failed-precondition" (preferred) or "already-exists" (if it's a resource) instead.
if (err.code === "auth/email-already-exists") {
throw new functions.https.HttpsError(
"invalid-argument",
"The email address is already in use by other account",
{ code: err.code }
);
}

What can I do to resolve this pusher error-JSON returned from auth endpoint was invalid, yet status code was 200?

I still have this problem after asking the same question here: JSON returned from auth endpoint was invalid, yet status code was 200 with no response. I've looked at similar questions and followed the
suggestions: setting my broadcast driver to 'pusher', uncommenting 'App/BroadcastServiceProvider' class in my app.config file, setting debug mode to false in my .env file, etc. I have also looked at pusher docs but the issue remains unresolved for me.
I have updated my previous attempt by adding '/broadcasting/auth/' auth endpoint and headers but still the same error. But I can now see a 302 redirect to the auth route then a 302 redirect to the login route then to the dashboard with a 200 response on laravel telescope, which I wasn't seeing before now. So this suggests to me that adding the auth endpoint ought to resolve the issue but it doesn't.
I also tried setting up and using a '/pusher/auth/' auth end point route and controller but it gave me a 'Failed to load resource: the server responded with a status of 405 (Method Not Allowed)' along with "Error: Unable to retrieve auth string from auth endpoint - received status: 405 from /pusher/auth, but not the previous invalid json error. I get this with a 'get' request to the controller but a 500-internal server error with a 'post' request. I really don't know which is correct.
This is my bootstrap.js file:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true,
authEndpoint: '/broadcasting/auth',
//authEndpoint: '/pusher/auth',
auth: {
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
}
}
});
This is one pusherController I created:
public function pusherAuth(Request $request)
{
$key = getenv('PUSHER_APP_KEY');
$secret = getenv('PUSHER_APP_SECRET');
$app_id = getenv('PUSHER_APP_ID');
$pusher = new Pusher($key, $secret, $app_id);
$auth = $pusher->socket_auth($_GET('channel_name'), $_GET('socket_id'));
return response($auth, 200);
}
I now know my vue frontend file that should receive and display the broadcast checks out and the issue has to do with resolving this pusher subscription error.
Any help will be appreciated.
Check your .env for the correct Broadcast driver:
BROADCAST_DRIVER=pusher
I was finally able to resolve this issue. The problem was entirely an authentication issue as the error messages pointed out. While I still don't know why the built in '/broadcast/auth' endpoint didn't work, my initial attempt to authenticate by creating a '/pusher/auth/' was wrong in the way I set up the route and controller.
The correct route set up should be 'post' and call a controller, using a closure based route didn't work for me. My previous (see above) implementation of the controller was also wrong.
This is the controller code that worked:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Pusher\Pusher;
class PusherController extends Controller
{
/**
* Authenticates logged-in user in the Pusher JS app
* For private channels
*/
public function pusherAuth(Request $request)
{
$user = auth()->user();
$socket_id = $request['socket_id'];
$channel_name =$request['channel_name'];
$key = getenv('PUSHER_APP_KEY');
$secret = getenv('PUSHER_APP_SECRET');
$app_id = getenv('PUSHER_APP_ID');
if ($user) {
$pusher = new Pusher($key, $secret, $app_id);
$auth = $pusher->socket_Auth($channel_name, $socket_id);
return response($auth, 200);
} else {
header('', true, 403);
echo "Forbidden";
return;
}
}
}
This is the final bootstrap.js file:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true,
authEndpoint: '/pusher/auth',
auth: {
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
}
}
});
And my route code in web.php:
Route::post('/pusher/auth', [PusherController::class, 'pusherAuth'])
->middleware('auth');
Pusher console log:
Pusher : : ["Event recd",{"event":"pusher_internal:subscription_succeeded","channel":"private-user.3","data":{}}]
vendor.js:41325 Pusher : : ["No callbacks on private-user.3 for pusher:subscription_succeeded"]

Change the HTTP status code with a Google Cloud Function Promise

My code checks if a user is authorized, if the user is, the proper code is run. If the user is not, it run reject() to reject the promise.
If I run the code authenticated, I get
{"error":{"status":"INVALID_ARGUMENT","message":"Bad Request"}}
I am trying to change the status code to Forbidden (code 403) which you would normally do with res.status(403) however since this is a promise it is different. How can I change the error code returned?
My code is as follows:
const cloudFunction = functions.https.onCall((data, context) => {
return new Promise(function(resolve, reject) {
auth.verifyIdToken(data.userId).then(function(decodedToken) {
if(claims.admin === true) {
// Run code if user has admin role
}
else {
reject()
// Return error code 403 because user does not have admin role
}
}).catch(err => reject(err)) // Return error code 401 because user is not logged in
})
});
You can't change the HTTP status for a callable function. Callable functions essentially take over and hide the HTTP protocol for the request and response. All you do is specify the input and output objects, and the SDKs handle everything else.
If you need to control the HTTP status of a response, you will have to use a regular HTTP type function instead. Then you will have full control over the request and response.

Angular 2 RC5 http error handling

I am new in Angular 2, in my Angular 2 project I create API call service that return json data.
this._http.post(this.url, body, options)
.map(response => response.json())
.catch(this.handleError);
Let say this service return 401 Http Response unauthorized and I tried get the status error, so I can redirect to Login Page and show error message
.subscribe(
login => this.login=login,
error => this.errorMessage = <any>error);
}
but why response code did not throw as error, and only show result
Failed to load resource: the server responded with a status of 401 (Unauthorized) and end the task ?
when I debug the code, the result generated in this line code
this.invoke = function () {
try {
return zone.runTask(self, this, arguments);
}
finally {
drainMicroTaskQueue();
}
};
}
any suggestion ?
Thank You

Resources