How to set auth role programically for tomcat 8.5 - authentication

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);

Related

Mapping role-names to from roles

I configured a LDAP realm for tomcat 7. It searches for someone in the group users, once found will authenticate them and allow them to access the application.
This is my realm:
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://adldap.mycompany.com:3268"
userSearch="(sAMAccountName={0})"
userSubtree="true"
userBase="DC=mycompany,DC=com"
roleSubtree="true"
roleName="CN"
userRoleName="memberOf"/>
It finds the user then searches for the corresponding role-names. This is my security constraints with roles in the web.xml.
<security-constraint>
<display-name>user</display-name>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>TRACE</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<auth-constraint>
<description>users</description>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
But the user will have roles that look like CN=Domain Users,CN=Users,DC=mycompany,DC=com. So my question is, is there a way I can map that role to the role-name of user? Otherwise I need to define my security constraints as such:
<security-constraint>
<display-name>user</display-name>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>TRACE</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<auth-constraint>
<description>users</description>
<role-name>CN=Domain Users,CN=Users,DC=mycompany,DC=com</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>CN=Domain Users,CN=Users,DC=mycompany,DC=com</role-name>
</security-role>
map that role to the role-name of user?
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://adldap.mycompany.com:3268"
userSearch="(sAMAccountName={0})"
userSubtree="true"
userBase="DC=mycompany,DC=com"
roleSubtree="true"
roleName="CN"
userRoleName="sAMAccountName"/>
This should (I could not test it) pull the attribute (sAMAccountName) from the user entry that is authenticated.
Have you tried using
<security-role-ref>
<role-name>CN=Domain Users,CN=Users,DC=mycompany,DC=com</role-name>
<role-link>user</role-link>
</security-role-ref>

web.xml security constraint combination of roles

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/

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 :)

adding security to embedded jetty

I have a problem configuring BASIC-auth in jetty
here's my web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>resources</web-resource-name>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>MyRealm</realm-name>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
and here's my java code where I try to add a LoginService
HashLoginService myrealm = new HashLoginService("MyRealm");
myrealm.setConfig("src/main/resources/jetty-realm.properties");
root.getSecurityHandler().setLoginService(myrealm);
my jetty-realm.properties file has following user
user: Lag976JGQdeosfQM,user
I can make a connection but I can't authenticate, and I'm stuck on this for a long time now, so whoever helps me out get's a free digital beer! ;)
Ok so I've found out what I didn't do,
you have to start a LoginService before you can use it so I changed my java code to
HashLoginService myrealm = new HashLoginService("MyRealm");
myrealm.setConfig("src/main/resources/jetty-realm.properties");
myrealm.start();
root.getSecurityHandler().setLoginService(myrealm);

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>