web.xml security constraint combination of roles - struts

Given that I cannot create any new role because they are created in a CAS server and I do not have any control over them, is there a way to protect a PDF file to be opened only if a user has both "customer" and "professional" roles?
In other words, considering the following three users:
user1 has only "customer" role
user2 has "customer" and "professional" roles
user3 has "customer" and "professional" roles
user4 has only "professional" role
only user2 and user3 should be allowed to see the PDF.
Basically, I would like to do something like:
<security-constraint>
<web-resource-collection>
<web-resource-name>auth</web-resource-name>
<url-pattern>/doc/profesionalCustomer.pdf</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>professional,customer</role-name>
</auth-constraint>
</security-constraint>
Is this even possible?
Thanks in advance

This is not possible using declarative security (i.e. via web.xml). You can only list roles that have access to a resource like in the following:
<security-constraint>
<web-resource-collection>
<web-resource-name>auth</web-resource-name>
<url-pattern>/doc/profesionalCustomer.pdf</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>professional</role-name>
<role-name>customer</role-name>
</auth-constraint>
however in this case you would grant access to all users that have either professional or customer role which is not what you want. There is no construct that allows you to grant access for a user that has a combination of roles.
One way you can go about it is to deal with it programmatically: direct a client to a servlet that examines whether the user is in both customer and professional role using HttpServletRequest#isUserInRole(String) and if it is forwards the request to the default servlet which retrieves the pdf. Furthermore if you want to defer what combination of roles are granted access to deployment time, rather then hard-coding it in the servlet you can have the granting servlet parameterized appropriately through /web-app/servlet/init-param or /web-app/context-param element of your web.xml.
The following is web.xml excerpt that would support this:
<servlet>
<servlet-name>PDF Retriever</servlet-name>
<servlet-class>com.stackoverflow.PDFRetrieverServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PDF Retriever</servlet-name>
<url-pattern>/docs/pdf/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>PDF Docs - customer and professional only</web-resource-name>
<url-pattern>/docs/pdf/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>PDF Docs Private</web-resource-name>
<url-pattern>/private/pdf/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name />
</auth-constraint>
</security-constraint>`
and here is coding for doGet of the servlet:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (request.isUserInRole("customer") && request.isUserInRole("professional")) {
String urlSuffix = request.getPathInfo();
RequestDispatcher rd = request.getRequestDispatcher("/private/pdf"
+ urlSuffix);
rd.forward(request, response);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}

I wanted to read a bit on this topic and found the below link quite useful :
http://www.devarticles.com/c/a/Java/Securing-Struts-Applications/1/

Related

How to set auth role programically for tomcat 8.5

I have the following config web.xml
<security-constraint>
<display-name>Login Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Login Protection</web-resource-name>
<url-pattern>/servlet/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Login Access</role-name>
</auth-constraint>
</security-constraint>
I have my own Login servlet which I have authenticated the user and created a session using
HttpSession session = request.getSession(true);
But how do I add the role name "Login Access" to the session?
I found I had to implement a JDBCRelam and use call in servlet to authenticate the session
request.login(username, password);

BASIC authentication does not show up the authentication popup for the constrained resource second time

I am trying the BASIC authentication mechanism. When i try to access the constrained resource second time the popup for username and password does not come up.
Following are the roles and users defined in my tomcat-users.xml
<role rolename="Admin"/>
<role rolename="Member"/>
<role rolename="Guest"/>
<user username="Annie" password="admin" roles="Admin, Member, Guest"/>
<user username="Diane" password="coder" roles="Member, Guest"/>
<user username="Ted" password="newbie" roles="Guest"/>
Following are the entries defined in my web.xml
<web-app>
<display-name>SecurityApp</display-name>
<servlet>
<servlet-name>BeerAppServlet</servlet-name>
<servlet-class>com.example.servlets.BeerAppServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BeerAppServlet</servlet-name>
<url-pattern>/Beer/AddRecipe</url-pattern>
</servlet-mapping>
<security-role> <role-name>Admin</role-name> </security-role>
<security-role> <role-name>Member</role-name> </security-role>
<security-role> <role-name>Guest</role-name> </security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>Update</web-resource-name>
<url-pattern>/Beer/AddRecipe/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
<role-name>Member</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
My webapp name is SecurityApp.
For the first time when i access my app as follows
http://localhost:8083/SecurityApp/Beer/AppRecipe i get the popup for entering the user name and password and i enter the following credentials username=Diane password=coder. After entering the above credentials the authentication is success.
For the second time when i type this url http://localhost:8083/SecurityApp/Beer/AppRecipe.
I dont get the authentication popup for username and password. Why is it so. can anyone please explain
By using basic access authentication the credentials are stored at client side (your browser).
The web browser takes care of creating a BASE64-Encode of username and password and send it automatically each time you request to the same page. This means that you are "logged in" immediately without re-entering your credentials.
You can just close and open your browser, to show the username/password dialog again.
Because the browser caches your credentials (username, password) for the page and authentication realm and automatically sends them the next time you visit the page. This is how BASIC authentication works. If you close (all instances of) the browser, it will ask for credentials again, unless it is configured to store them permanently. You can check this related question.

Appropriate practice for security-constraint in web.xml

I can restrict access to web application through defining (among other things) security-constraint in web.xml. Each security-constraint consist of 1) <web-resource-collection> which contains a set of restricted resources, and 2) <auth-constraint> which contains a set of authorized users (security roles) which can access web-resource-collection defined in this constraint .
So I think I can do either in each constraint a) define single resource (address) and a set of authorized users or b) define a set of resources (addresses) and a single authorized user.
Am I right? What my approach should be.
I for example defined constrains like this:
<security-constraint>
<display-name>ConstraintAdminUser</display-name>
<web-resource-collection>
<web-resource-name>adminResources</web-resource-name>
<url-pattern>/protected/admin/*</url-pattern>
<url-pattern>/protected/main/*</url-pattern>
<url-pattern>/protected/user/*</url-pattern>
<url-pattern>/protected/lang/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>AdminUserRole</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>ConstraintUserOnly</display-name>
<web-resource-collection>
<web-resource-name>userResources</web-resource-name>
<url-pattern>/protected/main/*</url-pattern>
<url-pattern>/protected/user/*</url-pattern>
<url-pattern>/protected/lang/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>UserOnlyRole</role-name>
</auth-constraint>
</security-constraint>
But I don't know if it is a "right way" to do :)

Redirecting to two different welcome-pages depending on the users role in Java EE 6/Glassfish

I have implemented FORM based authetication with Glassfish 3.1 + JDBCRealm + MySQL (MD5). I've got only two roles, user and admin. Everything is going great, I can see from the log that authentication is working in both cases as an uset and as an admin (Watch log below)
Q1: Is it possible to make two different index-files so that when user is admin, he/she goes to /admin/index.xhtml and when user is in role user he goes direct to faces/user/index.xhtml?
Q2: Now when I logged in as an user, I can still go to "admin side" with just writting the whole link straight to address field in a browser, why ja how to avoid that?
Q3: When I logged in as a user and I have ONLY faces/admin/index.xhtml in welcome file list, it redirects me to that file even if xml file tells something else, why?
<welcome-file-list>
<welcome-file>faces/admin/index.xhtml</welcome-file> *?? ----> it goes always here, cause it is the first one I think?*
<welcome-file>faces/user/index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>Admin Pages</display-name>
<web-resource-collection>
<web-resource-name>Protected Admin Area</web-resource-name>
<description/>
<url-pattern>/faces/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>User Pages</display-name>
<web-resource-collection>
<web-resource-name>Protected Users Area</web-resource-name>
<description/>
<url-pattern>/faces/users/*</url-pattern>
<!--url-pattern>/faces/users/index.xhtml</url-pattern-->
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/faces/loginForm.xhtml</form-login-page>
<form-error-page>/faces/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
</web-app>
LOG:
FINE: Login module initialized: class com.sun.enterprise.security.auth.login.JDBCLoginModule
FINEST: JDBC login succeeded for: admin groups:[admin, user]
FINE: JAAS login complete.
FINE: JAAS authentication committed.
FINE: Password login succeeded for : admin
FINE: Set security context as user: admin
FINE: [Web-Security] Setting Policy Context ID: old = null ctxID = jdbcrealm/jdbcrealm
FINE: [Web-Security] hasUserDataPermission perm: (javax.security.jacc.WebUserDataPermission GET)
FINE: [Web-Security] hasUserDataPermission isGranted: true
FINE: [Web-Security] Policy Context ID was: jdbcrealm/jdbcrealm
FINE: [Web-Security] Codesource with Web URL: file:/jdbcrealm/jdbcrealm
FINE: [Web-Security] Checking Web Permission with Principals : null
(Edit after myfear's answer)
-----In glassfish-web.xml I have roles like that. If I understood it correctly it means that admin belongs to groups: admin, customer and user. Customer belongs to groups: customer and user and User belongs to group user. Did I understand it correctly?
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
<group-name>customer</group-name>
<group-name>user</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>customer</role-name>
<group-name>customer</group-name>
<group-name>user</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>user</role-name>
<group-name>user</group-name>
</security-role-mapping>
</glassfish-web-app>
Thank you!
Sami
I've just attempted this as part of a University class and here's how I got the functionality I think you're after.
I'm using Netbeans with a Glassfish 4.1.1 server and have already configured the user roles in the servers file realm.
My project has 3 files:
index.xhtml
users/mainmenu.xhtml
admin/mainmenu.xhtml
The welcome page is set to index.xhtml with the following hyperlinks:
<h4>
<a href="/ED-Secure-war/faces/admin/mainmenu.xhtml">
Admin Login
</a>
</h4>
<h4>
<a href="/ED-Secure-war/faces/user/mainmenu.xhtml">
User Login
</a>
</h4>
In my web.xml security section I have the following roles configured
Now because access to each of these is restricted via the user groups, when you click on the hyperlinks on index you'll be prompted to login. If you enter a valid admin login for the admin link you'll be redirected to admin/mainmenu.xhtml, and vice versa for a user login.
A1) Welcome files aren't related to roles. If you need to do any kind of logic for dispatching users, you need to think about using boolean HttpServletRequest.isUserInRole(String role) or something similar to find out in which role the user is in.
A2) That shouldn't happen. You need to check the roles you have in your JDBCRealm. To what I see here, everything is configured the right way.
A3) I am not sure if I understand your remark "XML" file the right way. But welcome-files aren't bound to roles and .. see A1)
Thanks,
M
For your question 1: use the filter from where you can redirect the user to the specific page either userlogin.xhtml or adminlogin.xhtml
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String userName = SecurityAssociation.getPrincipal().getName();
String userNameSubject = SecurityAssociation.getSubject().toString();
System.out.println("Yeeey! Get me here and find me in the database: " + userName+ " Subject : "+userNameSubject);
filterChain.doFilter(servletRequest, servletResponse);
}

Bea Weblogic (8.1) and j_security_check

I'm working with a developer here who just inherited an existing site. It is a Weblogic 8.1 website with j_security_check authentication behind an apache reverse proxy. We're getting some issues with the logins, and are not sure about j_security_check config. It seems very black boxy and magicky. How do we get information on how it's configured, specifically how to change the target page after successful login.
Thank you.
weblogic will automaticly redirect to the requested page. In the web.xml is defined with resources are protected by the form-login (as it is called). So just request the first page and you will be presented with the login. After an successfull login you will be redirected to the original requested page.
You'll see something similar to this in your web.xml (the "myRoleName" will be replaced by the sercurity role as defined in your Webloggic Server Console under Security > Realms > myreal > Groups). If you have multiple roles, this will differ slightly.
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/flows/*</url-pattern>
<url-pattern>Controller.jpf</url-pattern>
<http-method>GET</http-method>
<http-method>Post</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>myRoleName</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>login.jsp</form-login-page>
<form-error-page>fail_login.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>
Only role for the Application
</description>
<role-name>myRoleName</role-name>
</security-role>