add admin path to symfoy back end with React js - reactjs

I'm currently working on symfony 4 project with React js to handle admin panel .
I used Webpack Encore to connect React JS .
the path of The React JS app is :
my_project_symfony/
And i have an api in :
my_project_symfony/api
The React JS is supposed to present the admin interface so it must be protected by admin role .
My security config is :
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
refresh:
pattern: ^/token/refresh
stateless: true
anonymous: true
With this configuration how can i protect my React JS admin interface with admin role and at the same time allow role user to use my api ?
I want to :
my_project_symfony/ReactJsAPP // Protected by admin role
my_project_symfony/api// Protected by user role

Related

"Authority mismatch on settings vs. signin state" with OIDC Client when trying to grant access between 2 client Applications

We have two .net core with angular applications where we have used Openid server and client
https://localhost:80 : Parent Application
https://localhost:85 : Child Application
We want to authenticate the child application within the parent application.
In the angular end, we used oidc-client and updated the UserManager dynamically inside the child application.
The flow we are trying to achieve is
Login Page child application (https://localhost:85) -> Click Login -> it redirects to parent app Login Page (https://localhost) -> entering credentials and After successful signing in the redirection URL will be (https://localhost:85) and it will grant access to that child application.
While redirecting to the child application by redirect URL after login it throws the below error "Authority mismatch on settings vs. signin state"
[![enter image description here][1]][1]
Can someone help me with the flow of authentication of multiple client applications via openid client ?
Error: authority mismatch on settings vs. signin state
at t [as _processSigninParams] (oidc-client.min.js:1:57198)
at t [as validateSigninResponse] oidc-client.min.js:1:55646)
at oidc-client.min. js:1:27449 at
ZoneDelegate. invoke (zone, js:372รท26) at Object.onInvoke (core.mjs:26356:33) at
ZoneDelegate. invoke (zone. js:371:52)
at Zone.run (zone. js:134:43)
at zone. js:1275:36 at
ZoneDelegate. invokeTask (zone. js:496:31)
at Object.onInvokeTask (core.mijs:26343:33)
Initially, the child application will have the below config
this.ChildAppConfig = {
authority: 'https://localhost',
client_id: 'child-spa',
redirect_uri: `https://localhost/signin-callback`,
scope: 'profile openid offline_access',
response_type: 'code',
post_logout_redirect_uri: `https://localhost/signout-callback`,
silent_redirect_uri: `https://localhost/silent-renew`,
automaticSilentRenew: false,
revokeAccessTokenOnSignout: true,
accessTokenExpiringNotificationTime: 60,
};
When I want to grant access to a child application via a parent application I will redirect it to the parent application, where the parent application will have the below config, and once authenticated it should redirect back to the child application
grantAccessConfig = {
authority: 'https://localhost:85',
client_id: 'spa',
redirect_uri: `https://localhost/signin-callback`,
scope: 'profile openid offline_access',
response_type: 'code',
post_logout_redirect_uri: `https://localhost/signout-callback`,
silent_redirect_uri: `https://localhost/silent-renew`,
automaticSilentRenew: false,
revokeAccessTokenOnSignout: true,
accessTokenExpiringNotificationTime: 60,
};
Ok i had this error before with Reactjs oidc-react and .net backend. the problem was that the configuration defined in SigninCallBack.js(here i init the storage and redirect) was not same as the configuration defined in identity server. this config was from the test app that throws that error
import React from 'react'
import { WebStorageStateStore } from 'oidc-client-ts';
import { UserManager } from 'oidc-react';
const SigninCallBack = () => {
var config = {
userStore: new WebStorageStateStore({store: window.localStorage}),
authority: "https://localhost:9001/",
client_id: "myappid",
redirect_uri: "https://localhost:3000/signincallback",
client_secret: "thesecretkey_but_i_used_PKCE",
response_type: "code",
scope:"openid profile someApi",
post_logout_redirect_uri : "https://localhost:3000/signout-callback-oidc",
loadUserInfo: true
};
var userManager = new UserManager(config);
userManager.signinCallback().then(res => {
window.location.href = '/';
});
}
export default SigninCallBack;
and mine was the client url which here i was defined with http but in the identityserver config i defined it with https. however it could be any of them such as response type ,client Id etc.

HWIOAuth Symfony 4: A service definition must be an array or a string starting with "#" but string found for servic

I'm trying to integrate the FOS with HWIO on Symfony 4. Unfortunately, I ran into an error as seen below:
In FileLoader.php line 168:
A service definition must be an array or a string starting with "#" but string found for service "class" in D:\web-projects\pcrmanagement\config/services.yaml. Check your YAML syntax in D:\web-projects\pcrmanagement\config/services.yaml (which is loaded in resource "D:\web-projects\pcrmanagement\config/services.yaml").
In YamlFileLoader.php line 336:
A service definition must be an array or a string starting with "#" but string found for service "class" in D:\web-projects\pcrmanagement\config/services.yaml. Check your YAML syntax.
Here are my code below, I'll go and post only what you need to see, if you need more code to review, I can put more.
#config/hwi_oauth.yaml
hwi_oauth:
firewall_names: [main]
fosub:
username_iterations: 30
properties:
googleplus: username
resource_owners:
google:
type: google
client_id: secret
client_secret: secret
scope: "email profile"
options:
csrf: true
# security.yaml
providers:
in_memory: { memory: ~ }
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
my_custom_provider: "/login/check-custom"
my_github: "/login/check-github"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
logout: true
anonymous: true
#services.yaml
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments: ['#fos_user.user_manager',{google: username}]
I think there is a problem on how he reads the arguments in services.yaml
Create your custom user_provider and extend HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider.
Then config your custom provider:
services:
App\Security\Core\User\MyFOSUBUserProvider:
arguments: ['#fos_user.user_manager', { facebook: facebook_id }]
Then change:
oauth_user_provider:
service: MyBundle\Security\Core\User\MyFOSUBUserProvider

Symfony API Rest login and register

I'm finishing developing a API rest with common endpoints using FOSUserBundle, FOSResBundle and FOSoAuthBundle.
In a parallel way, I'm developing another symfony app to consume the services but I'm having several doubts about how to register and login users via API endpoints. My idea is to have 2 controllers refered it's routes (such as /login and /register) and do this actions via api endpoint.
with FOSUserbundle this actions are simple but don't know how to 'consume' trough APIRest service.
I know it's only half an answer but I currently do this with login, but not registration (I don't need it).
I am using Symfony 4 and flex, but it should work on 3.4 I think. I am also using json.
Bundles
Bundles I use for this (on top of fosuser etc):
jms/serializer-bundle
lexik/jwt-authentication-bundle
friendsofsymfony/rest-bundle
Config
Fos Rest
fos_rest:
body_listener: true
param_fetcher_listener: force
format_listener:
enabled: true
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
view:
view_response_listener: 'force'
formats:
json: true
xml: false
rss: false
mime_types:
json: ['application/json', 'application/x-json']
routing_loader:
default_format: json
include_format: false
exception:
enabled: true
Fos User
fos_user:
db_driver: orm
firewall_name: api
user_class: App\Entity\User
from_email:
address: admin#example.com
sender_name: Admin
JMS Serializer
jms_serializer:
visitors:
xml:
format_output: '%kernel.debug%'
Lexik JWT
You need you generate tokens and put their location in your .env file. More info and a guide here.
lexik_jwt_authentication:
private_key_path: '%kernel.project_dir%/%env(JWT_PRIVATE_KEY_PATH)%'
public_key_path: '%kernel.project_dir%/%env(JWT_PUBLIC_KEY_PATH)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600 #whatever you like
token_extractors:
authorization_header: ~
cookie: ~
query_parameter: ~
Security
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
FOS\UserBundle\Model\UserInterface: sha512 #probably use bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_login:
pattern: ^/login
stateless: true
anonymous: true
form_login:
check_path: /login
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/, role: IS_AUTHENTICATED_FULLY }
Routes
login:
type: rest
resource: App\Controller\LoginController
Controller
I made a loginController that is really just a placeholder to override the route
<?php
namespace App\Controller;
use FOS\RestBundle\Controller\Annotations;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\Controller\Annotations\RouteResource;
/**
* #RouteResource("login", pluralize=false)
*/
class LoginController extends FOSRestController implements ClassResourceInterface
{
public function postAction()
{
throw new \DomainException('You should never see this');
}
}
Testing it
You can fire a POST request to /login and it should return a token!
{
"username": "my_user",
"password": "passw0rd"
}
Registration
I haven't actually done this but I have a simple enough idea...
Open a route to registration in your security.yaml
security:
firewalls:
api_register:
pattern: ^/register
anonymous: true
access_control:
- { path: ^/register$, role: IS_AUTHENTICATED_ANONYMOUSLY }
Register the route
registration:
type: rest
resource: App\Controller\RegistrationController
Write the controller method
Get the request data
User the FosUserManager to create a new user
- https://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html

Symfony 2.1 FOSFacebookBundle infinite loop after login

I've a little problem with the FOSFacebookBundle integration to my website. When I click on the "Connexion" button, user is redirected to /facebook/login_check, and some random token are added to the url (state and code). But a new value is given to these tokens every second, and the page is still blank.
Here is my code:
[config.yml]
security:
providers:
fos_userbundle:
id: fos_user.user_manager
my_fos_facebook_provider:
id: my.facebook.user
firewalls:
public:
pattern: ^/facebook
fos_facebook:
app_url: "http://www.facebook.com/apps/application.php?id=[MY_APP_ID]"
server_url: "http://localhost/[MY_APP]/app_dev/"
login_path: /facebook/login
check_path: /facebook/login_check
provider: my_fos_facebook_provider
default_target_path: /
anonymous: true
logout:
handlers: ["fos_facebook.logout_handler"]
main:
form_login:
login_path: /login
check_path: /login_check
provider: fos_userbundle
[routing.yml]
_security_check:
pattern: /facebook/login_check
_security_logout:
pattern: /logout
[layout.html.twig]
<script>
function goLogIn(){
window.location.href = "{{ path('_security_check') }}";
}
function onFbInit() {
if (typeof(FB) != 'undefined' && FB != null ) {
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.session || response.authResponse) {
setTimeout(goLogIn, 500);
} else {
window.location.href = "{{ path('fos_user_security_logout') }}";
}
});
}
}
</script>
Do you know why ?
Thanks in advance.
PS: I use Symfony 2.1 and FOSUserBundle.

FOSUserBundle redirect after Authentication Fails | redirect after logout

im using FOSUserBundle for Symfony2. How can i change the page redirection after a authentication failed and after a logout?
Thanks!
you can customize your form login in security.yml :
Example:
firewalls:
main:
form_login:
failure_path: /login_failure_redirect
logout:
target: /logout_redirect

Resources