因此,我尝试使用HWI-OAuthBundle和FoS-UserBundle,以便用户可以从我们的学校凭据进行连接。所以我应用了docs中的内容并配置了自定义资源所有者。
当我尝试登录时,我已正确地重定向到我登录的学校OAuth服务&授权客户端访问我的个人资料,但之后我收到此错误消息:
没有为资源所有者的实体定义属性' myecp'。
我尝试了几种我在互联网上找到的解决方案,但它们都不适合我。
这是我的代码: config.yml
#HWIOAuthBundle
hwi_oauth:
connect:
account_connector: my.myecp.user_provider
firewall_names: [secured_area]
fosub:
username_iterations: 30
properties:
myecp: myecp_id
resource_owners:
myecp:
type: oauth2
client_id: "%myecp_client_id%"
client_secret: "%myecp_secret%"
access_token_url: https://my.ecp.fr/oauth/v2/token
authorization_url: https://my.ecp.fr/oauth/v2/auth
infos_url: https://my.ecp.fr/api/v1/members/me
user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse
paths:
identifier: id
nickname: login
realname: [first_name, last_name]
mail: mail
options:
csrf: true
#FOSUserBundle
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Personnes
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
#Services
services:
my.myecp.user_provider:
class: AppBundle\Security\Core\User\FOSUBPersonnesProvider
arguments: ['@fos_user.user_manager', { myecp: myecp_id }]
security.yml:
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
fos_userbundle:
id: fos_user.user_provider.username
# in_memory:
# memory: ~
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
anonymous: ~
oauth:
resource_owners:
myecp: "/login/check"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
main:
# anonymous: ~
# activate different ways to authenticate
# http_basic: ~
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
access_control:
- { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
services.yml:
services:
# service_name:
# class: AppBundle\Directory\ClassName
# arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments:
- '@fos_user.user_manager'
- ['pass properties as array']
的routing.yml:
app:
resource: "@AppBundle/Controller/"
type: annotation
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /connect
hwi_oauth_connect:
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
hwi_oauth_login:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
myecp_login:
path: /login/check
logout:
path: /logout
FOSUBPersonnesProvider.php
class FOSUBPersonnesProvider extends BaseFOSUBProvider
{
/**
* {@inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
// get property from provider configuration by provider name
// , it will return `myecp_id` in that case (see service definition below)
$property = $this->getProperty($response);
$username = $response->getUsername(); // get the unique user identifier
//on connect - get the access token and the user ID
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
//we "disconnect" previously connected users
$existingUser = $this->userManager->findUserBy(array($property => $username));
if (null !== $existingUser) {
$existingUser->$setter_id(null);
$existingUser->$setter_token(null);
$this->userManager->updateUser($existingUser);
}
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {@inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$userId = $response->getUsername();
$user = $this->userManager->findUserBy(array('myecpId' => $userId));
// if null just create new user and set it properties
if (null === $user) {
$first_name = $response->getFirstName();
$last_name = $response->getLastName();
$email = $response->getEmail();
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
// create new user here
$user = $this->userManager->createUser();
$user->setPrenom($first_name);
$user->setNom($last_name);
$user->setMail($email);
$user->$setter_id($userId);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
return $user;
}
// else update access token of existing user
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
$user->$setter($response->getAccessToken());//update access token
return $user;
}
}
感谢您的帮助!
答案 0 :(得分:2)
首先更改文件services.yml行,其中您传递user.provider的参数。 例如,更改最后一行,下面是我谷歌的工作示例。
my.custom.user_provider:
class: YOURBUNDLENAME\Security\Core\MyFOSUBUserProvider
arguments:
- '@fos_user.user_manager'
- arguments: **[ @fos_user.user_manager, { google: googleID }** ]
接下来将$ property更改为User实体属性名称(myecp ??)的名称。在我的exmaple它的googleID。 $ property位于connect()方法下面的FOSUBPersonnesProvider.php中 我的User.php实体看起来像:
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="google_id", type="string", nullable=true)
*/
private $googleID;
我希望这会对你有所帮助
答案 1 :(得分:2)
我解决了这个问题。
因为这里将参数传递为value
:
/*form adjustments*/
<label for="Other-Animal"><input class="form_style" type="checkbox" id="Other-Animal" name="whatKindofAnimal[1]" value="Other: " />Other</label>
<input class="form_style" type="text" placeholder="Please Specify" id="otherKindofAnimal" name="textForOther" />
/*addition to your if(isset) php*/
if(array_key_exists(1,$_POST['whatKindofAnimal']))
echo $_POST['textForOther'];
更改为:
array
在FOSUserProvider合并数组HERE
中发送第二个参数时然后arguments: ['@fos_user.user_manager', { myecp: myecp_id }] //In Service
消息显示HERE
arguments: ['@fos_user.user_manager', myecp: myecp_id ]
如果您使用ERROR
:
protected function getProperty(UserResponseInterface $response)
{
$resourceOwnerName = $response->getResourceOwner()->getName();
if (!isset($this->properties[$resourceOwnerName])) {
throw new \RuntimeException(sprintf("No property defined for entity for resource owner '%s'.", $resourceOwnerName));
}
return $this->properties[$resourceOwnerName];
}
如果您使用Facebook
:
arguments: ['@fos_user.user_manager', facebook: facebook ]
如果您使用amazon
:
arguments: ['@fos_user.user_manager', amazon: amazon ]
如果您使用Odnoklassniki
:
arguments: ['@fos_user.user_manager', odnoklassniki: odnoklassniki ]
如果您使用github
:
arguments: ['@fos_user.user_manager', github: github ]