Diego Ramos
Diego Ramos

Reputation: 1059

What is the best approach to create a role based web application?

I need to create a web application for a School and I need to have different roles such as:

I need to have a login at the beginning and then after entering the credentials the application needs to redirect to the home page.

The question here is: How should I handle the roles? Should I have a namespace for each role? i.e: students/index.jsp, professors/index.jsp, admin/index.jsp or have a common namespace for all roles? something like home/index.jsp? and then use decorator/composite pattern to have the menus have different options based on the role?

For this question I know that I must store the users and the roles, each on in it's own table, this question is more related abour handling presentation/navigation/permission roles and how to create the webapp structure, i.e have a directory under webapp folder called students, another folder admin, and another one students and about the point I mentioned above (decorator or composite pattern)

Of course I am not making an app this small but I wanted to simplify the issues I am facing in order to create a big role web based application, and I believe these are the main principles.

Thank you for your time and help.

Upvotes: 19

Views: 23972

Answers (14)

Maral Kay
Maral Kay

Reputation: 47

Best approach would be : Spring Security

But it needs time and studying to do it the right way, so till then I do something like this:

  1. Say you have a table user in your database. Add a column name e.g. user_rights.
  2. In your application this column is a field of your User model class
  3. Create a method which checks this field and handles the roles as you wish

For instance, if a users role determines on what pages they have access, this is a simplified code example:

At the begining of your web-page:

<h:body>

<f:metadata>
    <f:viewAction action="#{userService.checkIfLogged()}" />
    <f:viewAction action="#{userService.accessCheck('page 2')}" />
</f:metadata>

and in your bean method:

@Override
@Transactional
public String accessCheck(String page) {
    try {
       HttpSession sess = Util.getSession();
       String user = sess.getAttribute("username").toString();
       Session session = this.sessionFactory.getCurrentSession();
       User logged = (User) session.createQuery("select u from User u where 
                     u.username = :logged").setParameter("logged", 
                                            user).uniqueResult();
       if (page.equals("page 1")) {
        if (logged.getRights().equals("simple")) {
            return "profile?faces-redirect=true";
        } 
        else {
            return "#";
        }
    }   ... etc.

Hope this is helpful, I still recommend Spring framework's features, but in the meantime this works perfect for me for small web apps.

Upvotes: 1

There are multiple approaches for this problem. For example, you can use a filter to authenticate and authorise the access of your resources to different users/roles. Other than this, Spring Security provides builtin mechanism to ensure authorised access to the web resources. Other than this, you can create an admin panel in your application, and you can assign different pages to different roles (but, this approach involves more programming work). You can also think to create security constraints in web.xml and you can associate web-resource-collections with different roles.

Upvotes: 0

tryingToLearn
tryingToLearn

Reputation: 11659

I believe you should go forward with Spring Security. It provides you many features out of the box and configuring and maintaining your application becomes so much easier. Also, you will be able to focus more on building the logic of your application while the library handles the Authentication and Authorization(the roles in simple words) for you. Plus it has a lot of community support.

Here is an example to get started: Spring security - hello world

From the example above, let me show a snippet of code to give more weight to my claim:

@Override
    protected void configure(HttpSecurity http) throws Exception {

      http.authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
        .and().formLogin();

    }

So what the above config will do is, whenever you try to access the /admin page or any url under admin pages e.g. /admin/profile, /admin/home etc., you will be asked to authenticate yourself ( with a username and password in your case). The spring security will check whether the username and password is correct. In addition to this, it will also check if the provided username has role admin. If both (password and role) check succeed, then only you will be allowed to access that page.

So with just few lines of code you are controlling entire security with role management for your application.

Although in the example post, hard coded usernames are used but plugging your db is also pretty easy. But the example is a good way to get started and see for yourself if it fits your use case.

Upvotes: 0

Sumesh TG
Sumesh TG

Reputation: 2575

Try to develop your web app using spring framework and spring security Please refer the below example http://websystique.com/spring-security/spring-security-4-role-based-login-example/

Upvotes: 0

P Laack
P Laack

Reputation: 11

I am in a similar situation right now. My Project(s) need Authentication and role-based Authorization. There are a number of solutions available for Java applications. Our team decided to use Keycloak, which is an extra app where you can handle most of the user management. It can run on a seperate server. Though, depending on the scope of your app, it might be overkill.

As I see it, you have not yet implemented any Authentication. That part is finished in my case and it was mostly done through configuration in Keycloak + web server.

Generally, you can use Java EE security for Authorization in most modern web servers. This will allow you to use Annotations like @RolesAllowed to grant or deny access and can work regardless of Keycloak. Examples. This way you can keep a unified structure for all your different roles and only decide the legitimacy of a request just before it is executed.

Upvotes: 0

rohit raj
rohit raj

Reputation: 69

you can create table based named like role_user based on that you can segregate

different roles

Upvotes: 0

amanzoor
amanzoor

Reputation: 399

You can create different roles to give access to different restricted areas. For example, you can have Student, Professor and Admin roles. Later you can allow or prevent the access to the content based on the roles. Spring Security may be good for you.

Upvotes: 1

Liem Le
Liem Le

Reputation: 591

I'm not sure my solution will work against your problem. But in my case, I do it as follow:

User 0..n --- 0..m Role

Role 0..n --- 0..m Privilege

Production code

In your case you may want:

  • Admin cannot view, edit student score.
  • Student can view score but cannot edit.
  • Professor can view, edit, add score.

You can do as below:

Role

  • ROLE_SCORE_EDITOR
  • ROLE_SCORE_VIEWER

Privilege

  • OP_READ_SCORE
  • OP_CREATE_SCORE
  • OP_UPDATE_SCORE
  • OP_DELETE_SCORE ---> Probably dont need this one but it enough for an example.

Role - Privilege

ROLE_SCORE_EDITOR

  • OP_READ_SCORE
  • OP_CREATE_SCORE
  • OP_UPDATE_SCORE

ROLE_SCORE_VIEWER

  • OP_READ_SCORE

User - Role

Admin (It's really depends on you, In my case I should leave it empty)

Professor

  • ROLE_SCORE_EDITOR

Studen

  • ROLE_SCORE_VIEWER

Then in your template just guard your view with user.hasPrivilege or user.hasRole. It's will work fine.

P/s: Sorry for my bad English. If you need any thing please comment below or comment into my gist

Upvotes: 5

DevEmani
DevEmani

Reputation: 15

Having different pages violates the DRY (Don't repeat yourself) principle. If you want a simple solution, add Filters in your web app and do your authorisation there (delegate to 3rd party app). You would need to add conditions in the jsp page at a group level so that it need not be changed every time.

You can also use Spring security and jdbc authentication.

Upvotes: 0

Peter G. Horvath
Peter G. Horvath

Reputation: 545

You definitely do NOT want to have separate pages ("namespaces") for different roles as that would almost inevitably lead to code duplication.

You should have a page for each function and restrict access based on the roles of the users. (e.g. some menu items are not visible for a Student, but shown for Professors and Admins.)

You absolutely should not try re-inventing the wheel for managing role based permissions, as there are battle proven frameworks for that purpose: as others pointed out already, in Java world, Spring and Spring Security is the way to go.

I think JSP as technology is getting aged, so you should probably start learning Angular instead.

Since getting a working Spring / Angular project setup is not trivial, I would recommend you to use JHipster application generator that guides you through the whole process with a wizard (you have to just answer some questions -- when asked about the type select monolithic web application): it then creates a working project configuration with role based security in place following modern recommendations.

If you want to learn about proper role based access control in a modern web application, looking at the solutions used in a JHipster generated application is I believe the best and fastest solution:

  • it uses Spring Security features to restrict calls in the Java backend: look for the usages of org.springframework.security.access.annotation.Secured annotation in the generated project
  • shows some custom frontend tricks to show/hide certain UI parts based on roles, like this: <h1 *jhiHasAnyAuthority="'ROLE_ADMIN'">Hello, admin user</h1>, which you could easily adopt to your own use case.
  • you can have a working project in like 2 minutes: ideal for learning (go for the most simple monolithic web application!)

Upvotes: 13

Bohdan Petrenko
Bohdan Petrenko

Reputation: 1155

There is no single answer to your question. Everything depends on the structure of the project. If there is much in common between the roles you mentioned, then it's better to use a single index.jsp for all roles. Then you do not have to duplicate the common logic (js and css libraries, custom common scripts, views and styles inclusion). If there is little in common between the roles, then it's better to have separate index.jsp files for each role, since single index.jsp file will be dynamically created during the execution of the program depending on selected role (I think it's still possible to fix by caching).

In our projects, we use an approach with a single index.jsp file. This is due in the first place to the fact that they have a lot of common logic. But in any case decision will be taken by you.

Additionally, if you are using Spring Security and it's possible to add new roles during the process of developing of the project, then the @PreAuthorize ("hasRole ('ROLE_USER')") approach will be not good. Because if you'll add new role to the data base you will have to add a lot of code to the project to grant this new role required access. So, in this case will be better to grant access via permissions. And create relationship many to many between roles <-> permissions

Upvotes: 2

Mahesh
Mahesh

Reputation: 39

Good question. Actually extension of this is complete authentication module For your small case A common page is the best solution. As per the role desired text boxes or fields will appear. For Example, in case Role Student: subject, roll number will be available. But in case Professor logs in into same page, he can see additional fields like numbers, attendance etc. Easiest solution can be: To Create a master table, with Name, Id, TYPE(With there type whether student/Professor/Admin etc.), and use this TYPE as the decisive factor for showing fields.

Upvotes: -2

Qasim Ali
Qasim Ali

Reputation: 107

I will recommend having a look at spring security https://projects.spring.io/spring-security/#quick-start

Upvotes: -2

You can use a field in your DB that saves the role, but you can read about ACL and RBAC.

Upvotes: -3

Related Questions