How to restrict access some part of module in ZendFramework 2 (i.e. only administrator can do some actions) - authentication

so!
I have a question: how to allow access some part of module only for adminisitrator, for example.
For example, I have module album. It has controllers index, delete, add, edit, full. I want full and index controller be available for all roles, but edit, delete and add action only for administrators.
What module I have to use to do that? I found Zend\Authentification.
Table is: username, password, role.
How to authentificate user?:
// do the authentication
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
// success: store database row to auth's storage
// system. (Not the password though!)
$data = $authAdapter->getResultRowObject(null, 'password');
$auth->getStorage()->write($data);
$this->_redirect('/');
} else {
// failure: clear database row from session
$this->view->message = 'Login failed.';
}
After that I will get access to user data, for example, by:
Zend_Auth::getInstance()->getIdentity()->username;
So, in action, in which I want to restrict access I just need to use:
if(Zend_Auth::getInstance()->getIdentity()->role == admin) {
redirect("auth/login");
}
Right?
The questions:
Is my suggestion about how to check user role in each contoller correct?
Do I understand correctly how to work with Zend\Authentification and restrict access to some actions? So in future I will just use same for each action, right?
Additional question: Does Aclmodule uses for managing permissions? So Acl is needed to help Zend_Auth with permissions, right?

To be able to do this you have to build or implement an ACL (Access Control List). You can also use a third party solution in combination with the earlier mentioned Zend_Auth (or any other authentication module). You can read more on Zend ACL here: Zend ACL introduction
You could for example also take a look at BjyAuthorize. This ACL module provides a complete authorization solution for your application but depends on ZfcUser for user authentication and registration. It might be a good way to get started.
If you are done building or implementing BjyAuthorize you can easily tie your access permission checking to your routes (but there are many other ways). You can see how this works here on the BjyAuthorize GitHub page
These modules will teach you a lot about how authentication and authorization can be build into your Zend Framework 2 application.

Related

Is it okay to use Firebase Auth SDK for Mobile app authentication on the frontend? [duplicate]

The Firebase Web-App guide states I should put the given apiKey in my Html to initialize Firebase:
// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
firebase.initializeApp(config);
</script>
By doing so, the apiKey is exposed to every visitor.
What is the purpose of that key and is it really meant to be public?
The apiKey in this configuration snippet just identifies your Firebase project on the Google servers. It is not a security risk for someone to know it. In fact, it is necessary for them to know it, in order for them to interact with your Firebase project. This same configuration data is also included in every iOS and Android app that uses Firebase as its backend.
In that sense it is very similar to the database URL that identifies the back-end database associated with your project in the same snippet: https://<app-id>.firebaseio.com. See this question on why this is not a security risk: How to restrict Firebase data modification?, including the use of Firebase's server side security rules to ensure only authorized users can access the backend services.
If you want to learn how to secure all data access to your Firebase backend services is authorized, read up on the documentation on Firebase security rules. These rules control access to file storage and database access, and are enforced on the Firebase servers. So no matter if it's your code, or somebody else's code that uses you configuration data, it can only do what the security rules allow it to do.
For another explanation of what Firebase uses these values for, and for which of them you can set quotas, see the Firebase documentation on using and managing API keys.
If you'd like to reduce the risk of committing this configuration data to version control, consider using the SDK auto-configuration of Firebase Hosting. While the keys will still end up in the browser in the same format, they won't be hard-coded into your code anymore with that.
Update (May 2021): Thanks to the new feature called Firebase App Check, it is now actually possible to limit access to the backend services in your Firebase project to only those coming from iOS, Android and Web apps that are registered in that specific project.
You'll typically want to combine this with the user authentication based security described above, so that you have another shield against abusive users that do use your app.
By combining App Check with security rules you have both broad protection against abuse, and fine gained control over what data each user can access, while still allowing direct access to the database from your client-side application code.
Building on the answers of prufrofro and Frank van Puffelen here, I put together this setup that doesn't prevent scraping, but can make it slightly harder to use your API key.
Warning: To get your data, even with this method, one can for example simply open the JS console in Chrome and type:
firebase.database().ref("/get/all/the/data").once("value", function (data) {
console.log(data.val());
});
Only the database security rules can protect your data.
Nevertheless, I restricted my production API key use to my domain name like this:
https://console.developers.google.com/apis
Select your Firebase project
Credentials
Under API keys, pick your Browser key. It should look like this: "Browser key (auto created by Google Service)"
In "Accept requests from these
HTTP referrers (web sites)", add the URL of your app (exemple: projectname.firebaseapp.com/* )
Now the app will only work on this specific domain name. So I created another API Key that will be private for localhost developement.
Click Create credentials > API Key
By default, as mentioned by Emmanuel Campos, Firebase only whitelists localhost and your Firebase hosting domain.
In order to make sure I don't publish the wrong API key by mistake, I use one of the following methods to automatically use the more restricted one in production.
Setup for Create-React-App
In /env.development:
REACT_APP_API_KEY=###dev-key###
In /env.production:
REACT_APP_API_KEY=###public-key###
In /src/index.js
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
// ...
};
I am not convinced to expose security/config keys to client. I would not call it secure, not because some one can steal all private information from first day, because someone can make excessive request, and drain your quota and make you owe to Google a lot of money.
You need to think about many concepts from restricting people not to access where they are not supposed to be, DOS attacks etc.
I would more prefer the client first will hit to your web server, there you put what ever first hand firewall, captcha , cloudflare, custom security in between the client and server, or between server and firebase and you are good to go. At least you can first stop suspect activity before it reaches to firebase. You will have much more flexibility.
I only see one good usage scenario for using client based config for internal usages. For example, you have internal domain, and you are pretty sure outsiders cannot access there, so you can setup environment like browser -> firebase type.
The API key exposure creates a vulnerability when user/password sign up is enabled. There is an open API endpoint that takes the API key and allows anyone to create a new user account. They then can use this new account to log in to your Firebase Auth protected app or use the SDK to auth with user/pass and run queries.
I've reported this to Google but they say it's working as intended.
If you can't disable user/password accounts you should do the following:
Create a cloud function to auto disable new users onCreate and create a new DB entry to manage their access.
Ex: MyUsers/{userId}/Access: 0
exports.addUser = functions.auth.user().onCreate(onAddUser);
exports.deleteUser = functions.auth.user().onDelete(onDeleteUser);
Update your rules to only allow reads for users with access > 1.
On the off chance the listener function doesn't disable the account fast enough then the read rules will prevent them from reading any data.
I believe once database rules are written accurately, it will be enough to protect your data. Moreover, there are guidelines that one can follow to structure your database accordingly. For example, making a UID node under users, and putting all under information under it. After that, you will need to implement a simple database rule as below
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
No other user will be able to read other users' data, moreover, domain policy will restrict requests coming from other domains.
One can read more about it on
Firebase Security rules
While the original question was answered (that the api key can be exposed - the protection of the data must be set from the DB rulles), I was also looking for a solution to restrict the access to specific parts of the DB.
So after reading this and some personal research about the possibilities, I came up with a slightly different approach to restrict data usage for unauthorised users:
I save my users in my DB too, under the same uid (and save the profile data in there). So i just set the db rules like this:
".read": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()",
".write": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()"
This way only a previous saved user can add new users in the DB so there is no way anyone without an account can do operations on DB.
Also adding new users is posible only if the user has a special role and edit only by admin or by that user itself (something like this):
"userdata": {
"$userId": {
".write": "$userId === auth.uid || root.child('/userdata/'+auth.uid+'/userRole').val() === 'superadmin'",
...
EXPOSURE OF API KEYS ISN'T A SECURITY RISK BUT ANYONE CAN PUT YOUR CREDENTIALS ON THEIR SITE.
Open api keys leads to attacks that can use a lot resources at firebase that will definitely cost your hard money.
You can always restrict you firebase project keys to domains / IP's.
https://console.cloud.google.com/apis/credentials/key
select your project Id and key and restrict it to Your Android/iOs/web App.
It is oky to include them, and special care is required only for Firebase ML or when using Firebase Authentication
API keys for Firebase are different from typical API keys:
Unlike how API keys are typically used, API keys for Firebase services are not used to control access to backend resources; that can only be done with Firebase Security Rules. Usually, you need to fastidiously guard API keys (for example, by using a vault service or setting the keys as environment variables); however, API keys for Firebase services are ok to include in code or checked-in config files.
Although API keys for Firebase services are safe to include in code, there are a few specific cases when you should enforce limits for your API key; for example, if you're using Firebase ML or using Firebase Authentication with the email/password sign-in method. Learn more about these cases later on this page.
For more informations, check the offical docs
I am making a blog website on github pages. I got an idea to embbed comments in the end of every blog page. I understand how firebase get and gives you data.
I have tested many times with project and even using console. I am totally disagree the saying vlit is vulnerable.
Believe me there is no issue of showing your api key publically if you have followed privacy steps recommend by firebase.
Go to https://console.developers.google.com/apis
and perfrom a security steup.
You should not expose this info. in public, specially api keys.
It may lead to a privacy leak.
Before making the website public you should hide it. You can do it in 2 or more ways
Complex coding/hiding
Simply put firebase SDK codes at bottom of your website or app thus firebase automatically does all works. you don't need to put API keys anywhere

Can we restrict users in identity server4 to specific applications?

I am trying to implement IdentityServer 4 for enterprise scenario.
I understand that users are registered against Identity server.
My question is how to give permissions to users against applications, like as users are needed to assign to a particular application, if not assigned application should return unauthorized.
If a user needs to access multiple applications then multiple assignments are needed.
I am looking a way for Identity server to invalidate the submitted token if the user doesn't have access to the application in a single go, even though the challenged token might be valid if it is submitted by other application which the user has access to
Identity Server absolutely handles authorizations on the most basic level. It creates authorization codes and access_tokens that are essential in an applications authorization. Without them you cannot get authorized. Thus for others to claim Identity Server does not do authorizations is flat out wrong.
I came in here a week ago looking for a solution for this very same problem. I want to restrict users to specific applications by not granting them access tokens if they fail to meet certain parameters, in my case a UserClient table. Lucky for you I have a solution. Identity Server 4 implements a few, what they call, CustomValidators that occur at the time of authorization or token creation. They are
internal class DefaultCustomAuthorizeRequestValidator : ICustomAuthorizeRequestValidator
internal class DefaultCustomTokenRequestValidator : ICustomTokenRequestValidator
public class DefaultCustomTokenValidator : ICustomTokenValidator
There name really says it when they get called. Each one contains a single method
public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
{
return Task.CompletedTask;
}
Notice something? That's is right! It does nothing. Almost as if they are meant to be replaced. (It is).
This is the area that you can add your custom logic to reject the request. CustomAuthorizeRequestValidationContext contains ClientId and User claim information. It also contains a boolean value called IsError. Simply set that to true and whamy! Access denied. You can also set error messages etc. Here is an example that implements the ICustomAuthorizeRequestValidator inface that will restrict a user based on there user Id
public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
{
var sub = context.Result.ValidatedRequest.Subject.FindFirst("sub");
if (sub != null && sub.Value != "88421113")
{
context.Result.IsError = true;
context.Result.Error = "Unauthorized";
context.Result.ErrorDescription = "You are not authorized for this client";
}
return Task.CompletedTask;
}
Feel free to inject a dbcontext or two to read off of your userclient table. I check the sub claim to be null because this will get hit several times before actual login occurs.
From what I noticed all three behave similar in terms of use, but different in terms of outcome. Setting an error ICustomAuthorizeRequestValidator will prevent the redirect to your client and instead direct you to the Identity Server error screen. The other two will redirect back to the client and generally throw some throw some sort of HttpResponse error. Therefore replacing the ICustomAuthorizeRequestValidator seems to work best.
So simply created a class that implements ICustomAuthorizeRequestValidator. Then add that into your identity services like so
services.AddIdentityServer().AddCustomAuthorizeRequestValidator<MyCustomValidator>()
and you are done done.
You can add a claim in your IdentityServer4's claims table called "role" and in your application, add some UI to authorize a person via email or similar, and then set his/her role in the claims db. And you can also delete the authorized user from your application, which should un-assign a role to that particular person. Thus he/she although is successfully authenticated, can't use your application because you have authorized then. Hope this approach helps you!
For users, IdentityServer is authentication only. Authorization should be handled by your application.
Authentication = Verifying who a user is
Authorization = Verify what a user can do
Update
I wrote an article on this topic to clarify how OAuth 2.0 does is not user-level authorization. Hope it helps! https://www.scottbrady91.com/OAuth/OAuth-is-Not-User-Authorization
As Scott says, Identity Server will authenticate that the user is who they say they are, not explicitly tell you what that user can do.
You can use the claims returned as part of that authentication to then perform authorization checks within your app. For example, you might use the sub or id claims to perform checks from your app on whether the user associated with that sub/id is allowed to access a specific resource.
The water gets a bit muddier when you bring role claims into the picture, but so long as you appreciate the difference between authentication and authorization you should be ok.
In our enterprise scenario we split it into layers:
We introduced a tenant -- a customer (organization) of our enterprise
solution.
Then we have roles (not more than 20 or so) assigned for
each particular user.
IdentityServer fetches users from tenant and access APIs. The only pre-check it performs is that a particular client (application), requested a token, is not restricted for the particular tenant (customer-level licensing), otherwise we display a message and block the challenge response.
Then we come to an app. With a valid token, having tenant and roles inside. The roles-to-functions assignment could be unique within the tenant. So the application itself performs a granulate permissions check, using a separate API. The application is free to enable-disable some functions or even redirect to the special page in IdSrv "Access denied for the app".
With such approach we are scalable, we are configurable, we are as fast as we want. In previous generation we had "all in one" identity+access+licensing monster-like system, and we decided to split. Today we do not face any real limits with adding new customers (tenants), having 20000 users in average each.
Another way, you can redirect user back to respective client login page it they are not assigned to application/client by using IProfileService of IdentityServer4.Services
public async Task IsActiveAsync(IsActiveContext context)
{
if (!string.Equals("MyAllowedApplicationId", context.Client.ClientId, StringComparison.OrdinalIgnoreCase))
{
context.IsActive = false;
}
}
You have to set IsActive = false to redirect user back to login page where user can login with user details which is allowed in application

Yii multiple user login in an application

I am a new in Yii framework, I just setup an application and separate front-end & Back-end part. Both User can register / log in properly. Now I want to login different user from front-end site.
Example : Front-End user are tow types
1. Customer
2. Merchant
I want to set different role of theme. How to possible it, Please share with me.
You will probably need to use Yii's RBAC. In order to implement and use RBAC in yii you need to follow the following steps:
1-configure main.php which is located at '/path/to/yourApp/protected/config/main.php'
'authManager'=>array(
'class'=>'CDbAuthManager',
'connectionID'=>'db', //your database config name
),
2-import yii's rbac database scheme into your database. You can find it under /path/to/yii/framework/web/auth/ directory
3-add your operations. Operations such as 'VIEW_POST' or 'EDIT_POST':
$auth=Yii::app()->authManager;
$auth->createOperation('VIEW_POST','view a post');
$auth->createOperation('EDIT_POST','edit a post');
4-create your roles. For example in your case you will have two roles. First Customer and second Merchant.
$role=$auth->createRole('CUSTOMER');
5- Assign operations to your roles:
$role->addChild('VIEW_POST');
6- All done! You can restrict the access like below:
if(Yii::app()->user->checkAccess('VIEW_POST'))
{
//user has access to view a post
}else{
//logged in user has no access to view a post
}
You can also check access with role like below:
if(Yii::app()->user->checkAccess('CUSTOMER')) {}
In order to assign a role to a user use the assign method:
$auth->assign('CUSTOMER','USERNAME | USER ID'); //user will hold the CUSTOMER ROLE
It might also be noted that, I assumed that you have implemented your authentication class. You can find more about Yii's RBAC and authentication in the following link which is Yii's official document:
Yii Authentication and Authorization

What is the most secured way to check if a user is already logged in?

I have read many questions like my question title, none of them give me a solution.
I am implement a website (using struts2 framework) and I dont know what is the most secure way to check if user is already logged or not. My site has the payment feature, so I should really be careful about this.
All the solution I have read are similar like this:
// Is there a "user" object stored in the user's HttpSession?
Object user = session.getAttribute (USER_HANDLE);
if (user == null) {
// The user has not logged in yet.
}
else {
// the user has logged in
}
I was wondering is there any chance some bad guys can create a fake session object like the user object and then can logged in the system without a valid password?
I also want to know is it practice way, at every required logged in page, not just check the user object is not null, but also check the username and password in the database?
Maybe you should use a security framework like spring security or Apache Shiro.
Security issues are always based on your requirements, in simple which kind of security you want ,because there are various layers of security regarding web. But as you have mentioned, This you can achieve using Struts2-Interceptors, because It provides you terminology to perform some essential operation before and after your action is called.For example refer this link.

Play Framework User Authentication/Membership

I want to support user authentication in a Play Application. It is Web App and I think that the built-in "Secure" module is too simple for my needs. In fact, the user group discusses how the Secure module is really for demonstration purproses. However, how can I develop such a system?
Essentially, the application will allow the user to login and then they will have their own settings and so forth applied throughout the application. There are some pages for which unauthenticated users can view but if the client is authenticated, then the view of those pages will be different. Pretty simple setup but most documentation just refers to the simple Secure module.
If your only special requirement is that some pages be publicly visible, I've got your answer: Play framework: How to require login for some actions, but not all . I just copied the Secure module and made a few small additions.
You can use the PlayPlugins for this. I started to write a plugin which enabled Security in powerful way. It's an migration from BasisSecurity for Grails. At the moment I don't find the time to further development. You can see the current state here https://code.launchpad.net/~opensource21/+junk/permsec.
from your requirements the current authentication module seems enough. If not, what I did for my project was:
Copy the classes from the module (Secure controller, the annotation, the tag) to your project
Extend the controller adding additional functionalities
I don't have my code handy to put samples here, but in general I:
renamed the classes (so apologies if I say one name meaning another, don't remember the original names!)
added methods in Secure Controller to handle OpenId and OAUth authentication
added support methods in my User model that given the Id of a service (Google OpenId, Twitter id, etc) returns an existing user from the DB with that ID, or if it doesn't exists creates and returns a new user linked to that id.
added some flags (like admin, supervisor, etc) to User class
modified the check method in security controller so it checks the values of the annotation with the flags of the user. Something like (pseudocode)
var ok : Boolean = false
ok = ok || (annotation.value == "admin" && currentUser.isadmin)
ok = ok || (annotation.value == "supervisor" && currentUser.issupervisor)
...
added the annotation to the corresponding methods, and added the Secure controller (via #With) tot he classes that require access check
With this I have a secured system, and it seems to work quite well (fingers crossed :P)
Don't know if it could help you but look at the deadbolt module to manage access rights to views/controllers...
http://www.playframework.org/modules/deadbolt-1.0/home