Security constraint in web.xml for authenticated users without role memberships - java

I am quite desperate, because I think there must be an easy solution to my problem but I am searching - to no avail.
I am using a custom Realm in Glassfish 3.1.1. This custom realm (implements AppservPasswordLoginModuleInterface) takes a security token from the HTTPS request, validates the security token and then returns the user to Glassfish.
The problem is that the security token does not contain any groups, meaning that the method public String[] getGroupsList() or the custom realm returns an empty list (correctly, because there are no roles in the security token).
That said, I would like to have a security contraint that only validated users can login. I know that I can use the following constraint in web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>mywebapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Users</role-name>
</auth-constraint>
</security-constraint>
But because I don't have any groups, I cannot map any groups to roles, and therefore I cannot use the auth-constraint with role-name.
Is there a way in web.xml to define that only authenticated users are allowed, ignoring in which role they are and ignoring whether they are in any role at all.
There are a couple of solutions which I cannot implement:
I cannot change the underlying LDAP to include roles, because the LDAP schema and the way how LDAP users are mapped to security tokens our out of scope.
I have to use the current custom realm handler, I cannot replace it with one of my own which just returns a default group. I did try this once, and it worked. But I cannot replace the existing custom realm with my own because the custom realm should be generic.
But I really think there should be a way in web.xml just to say: Ignore all groups and roles, I just want an authenticated user?
Any help would be appreciated.

Pretty old, but for those looking for an answer, you can use an * role name:
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
This guy managed to solve it.

Use two asterisks:
<auth-constraint>
<role-name>**</role-name>
</auth-constraint>
See section 13.8 of the Servlet 4.0 spec: https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf
The single asterisk means a user must have at least one of any declared role vs double asterisks means a user simply must be authenticated. So with single asterisk a user must have one of the roles declared in the security-role section of the web.xml, and it appears some application servers (like JBoss/Wildfly) allow you to also put a single asterisk in this section to make this work similarly to the double asterisks. This single asterisk in the security-role section appears to be non-standard and likely non-portable:
<security-role>
<role-name>*</role-name>
</security-role>

Related

What is the authenticated uesr's role - Java

Good morning
I am using ejb2 (older application) on weblogic 10.
There are methods in my session beans that are secured to be executed by certain role.
Each of my ejb interface method I annotate with
`#ejb.permission role-name="role1, role2"`
Since some methods maybe executed by users in few different roles, how can I tell which role runs the method?
I know how to know if a "caller is in a certain role"
Principal principal = ctx.getCallerPrincipal() ;
boolean isRole = ctx.isCallerInRole("role2") ;
But, is there a way to obtain the actual caller's role? Something like "getCallerRole()" or such?
In the xml file "ejb-security-roles.xml" I specify what roles are in application domain
<security-role>
<role-name>role1</role-name>
<role-name>role2</role-name>
</security-role>
Then, each of those roles are mapped to LDAP in the "weblogic-security-role-assignment.xml"
<security-role-assignment>
<role-name>role1</role-name>
<principal-name>Role1User</principal-name>
</security-role-assignment>
<security-role-assignment>
<role-name>role2</role-name>
<principal-name>Role2User</principal-name>
</security-role-assignment>`
Can anyone help, directing me to the right path of thinking?
Just use if (ctx.isCallerInRole("role2")) {
According to Oracle Accessing an Enterprise Bean Caller’s Security Context,
it is only way to check user's role.

Case insensitive check for role in HttpServletRequest

The javax.servlet.http.HttpServletRequest class has a method called isUserInRole. I use this to check if a user has, for example, the admin role. However, that method is case sensitive. So, if the role in the request was Admin or ADMIN, then isUserInRole("admin") would be false. I use the isUserInRole method in a number of places accross multiple applications to check for a number of different roles.
Is there a way to achieve the isUserInRole functionality case-insensitively that does not require checking each different possible case combination with isUserInRole?
You could implement a filter that wraps requests using a HttpServletRequestWrapper - implement your HttpServletRequestWrapper to override the isUserInRole() method to make it case-insensitive (eg, configure all roles in upper-case, test role params by converting to upper-case).
A quick search will find plenty of HTTPServletRequestWrapper examples...
http://docs.oracle.com/javaee/6/tutorial/doc/gjiie.html
Just map multiple role names to the admin role:
<servlet>
<security-role-ref>
<role-name>admin</role-name>
<role-link>admin</role-link>
</security-role-ref>
<security-role-ref>
<role-name>Admin</role-name>
<role-link>admin</role-link>
</security-role-ref>
</servlet>
<security-role>
<role-name>admin</role-name>
</security-role>

Check if a user is enabled with Glassfish 4 JDBCRealm

I'm trying to create a login page which authenticates the users via a JDBCRealm on my Glassfish server (i think this is the easiest way), so far i managed to get it working.
But in the User table in the DB i have a "is_active" column, when this column contains "false", i would like the server to reject the login attempt (just like with a wrong password).
I'm fairly new to java ee and have no idea where i should be looking for this. Does anyone know how to do so?
First of all I have no earthly reason why glassfish does not provide a better default security realm. JDBCRealm does not support salted user passwords, and also does not support the more modern hashing techniques such as PBKDF2 etc...
That being said, I think if you want to use the default JDBCRealm, here is a way to make it enforce access to certain pages for only "active" users.
Have three tables similar to the ones below (these are for postgres).
CREATE TABLE users
(
user_id serial PRIMARY KEY,
email character varying(255) NOT NULL UNIQUE,
passhash character varying(255) NOT NULL
);
CREATE TABLE users_groups
(
users_groups_id serial PRIMARY KEY,
user_email character varying(255) NOT NULL REFERENCES users(email),
group_name character varying(20) NOT NULL REFERENCES groups(group_name)
);
CREATE TABLE groups
(
group_name character varying(20) PRIMARY KEY
);
Instead of an is_active column on the users table, make an "active" group. Then you can enforce access to portions of your web app to members of that group/role (make sure to set up the mapping between groups and roles properly).
For example, if you wanted all urls to only be accessible by "active" users, you could put something like the below in your web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>private</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>active</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
I assume you got your password hashing code working properly, and the db tables set up successfully with glassfish? It is arguably a pain in the neck.
Documentation on working with roles/groups:
http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html

Servlet Filter - Dont apply filter to a specific one

I have a web-application with login screen backed up by an Authentication Filter.
I have the following in my web.xml
<filter>
<filter-name>AuthenticationFilter</filter-name>
<display-name>AuthenticationFilter</display-name>
<filter-class>com.mycompany.secutity.AuthenticationFilter</filter-class>
</filter>
And I have the following mapping -
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
But now I want to add an exception where for a specific servlet /web/MyNewServlet, I want to bypass the authenctication filter. How can we do this?
There are two ways in which you could do this:
Remap the /* pattern to another pattern like /subdir/*, and thereby avoid the AuthenticationFilter from being applied against /web/MyNewServlet. This is a cumbersome process as you might have several URLs in your web-application that now need to be remapped. I would suggest doing this early in your development, or when you do not have too many URLs to remap.
Include an exclusion rule programatically inside your Filter implementation. You will need to use HttpServletRequest.getServletPath and similar methods to verify if the URL fragment contains /web/MyNewServlet, and then chain the filter to the next filter or the servlet, instead of executing the body of the filter.
Extending Vineet's idea slightly, you could add another filter, called something like DoesNotNeedAuthenticationFilter, which runs before the AuthenticationFilter, and just sets an attribute DOES_NOT_NEED_AUTHENTICATION on the request. The AuthenticationFilter can then check for that attribute, and pass any requests which have it. You can then use the normal filter mapping mechanism to apply the DoesNotNeedAuthenticationFilter to the appropriate URLs or servlets.

url-pattern and wildcards

While configuring the security constraints for a web-module's roles in J2EE application I'm having the following problem:
Application:
Giving a servlet named customersServlet, which receives two parameters in the URL:
A string representing an operation (INS, UPD, DLT and DSP).
An identification number to identify a customer on which the operation will be performed.
E.G.: the url /servlet/cusotmersServlet?UPD,5 is used to update customer number 5 data, and the url /servlet/customersServlet?DLT,8 is used to delete customer number 8.
Problem:
If I use this security-constraint the servlet can only be accessed by the role specified, which is ok:
<security-constraint>
<web-resource-collection>
<web-resource-name>...</web-resource-name>
<url-pattern>/servlet/clientsServlet*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>clientAdmin</role-name>
</auth-constraint>
</security-constraint>
But I want to restrict the ability to insert customers only to a role named clientAdmin.
I've tried several url patterns but none of them works as I want (all of them allow every role to access the servlet with any parameter):
<url-pattern>/servlet/clientsServlet?INS,*</url-pattern>
<url-pattern>/servlet/clientsServlet?INS/*</url-pattern>
...
How to use the wildcard * in the url-pattern tag?
Note: The application cannot be changed, so I need a solution that only implies touching the deployment descriptor.
The <url-pattern> tag only allows a very restricted subset of wildcards. This is probably not what you are used to from other situations, where a * can be used at any position. You can download the Servlet specification here:
http://jcp.org/aboutJava/communityprocess/mrel/jsr154/index2.html
Section SRV.11.2 of that document describes how these URL patterns are interpreted. In particular, the * does not mean "zero or more arbitrary characters" here.
Note: The application cannot be changed, so I need a solution that only implies touching the deployment descriptor.
Not sure if this counts as an application change - perhaps you could think of it as a plug-in. You could add a Filter. This would require the ability to add a new JAR to WEB-INF/libs and the ability to define the filter in web.xml. The Filter would allow you to restrict access programmatically.

Categories

Resources