I have three jsf web application deployed on tomcat web server with SSL/TLS enabled. Now I want to build some kind of SSO authentication with particular roles. In tomcat conf/server.xml there is line:
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
so I got idea that tomcat maybe have his own SSO implementation. Does anyone know where to find more information about this or some code examples?
Thanks in advance
After many hours of research I found solution, so I will post it here in case someone need SSO authentication in tomcat.
First of all open conf/server.xml file in tomcat installation directory and add following line:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
</Host>
By doing this, you have opened SSO valve. Next, you need to set up roles in tomcat. That is done by editing conf/tomcat-users.xml. Scroll to the bottom and add roles, something like this:
<role rolename="CUSTOMER"/>
<role rolename="ADMIN"/>
Now, if you want plain text authentication you can add users also by adding :
<user username="admin" password="admin" roles="ADMIN"/>
<user username="customer" password="customer" roles="CUSTOMER"/>
or, if you have database you can set up connection with database server in conf/server.xml, I'm using MySQL:
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/databaseName?user=serverUsername&password=serverPassword"
userTable="usersTable" userNameCol="usernameColumnName" userCredCol="passwordColumnName"
userRoleTable="roleTable" roleNameCol="roleColumnName"/>
Note: You need to provide connection driver in tomcat lib directory.
More info on: https://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html#JDBCRealm
Finally in your web app or apps, find web.xml and add security constrains:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Context</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>this is ignored currently</realm-name>
</login-config>
<security-role>
<role-name>ADMIN</role-name>
</security-role>
Note: if you have custom Login page you can edit <login-config> tag and change to following:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>file</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
Cheers.
Apache 9 Single Sign On Valve documentation is here: https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html.
Since you mentioned JSF (I'm not sure if you are using PrimeFaces & OmniFaces), maybe you are struggling also with log out/session time out. Specially if end user has open multiple windows/tabs and multiple applications (you mentioned you have three JSF apps), then
OmniFaces FacesExceptionFilter and
OmniFaces FullAjaxExceptionHandler
would be helpful for you. I can also recommend the best JSF book I've ever read
The Definitive Guide to JSF in Java EE 8 written by BalusC (JSF expert, author of OmniFaces, etc.).
Related
I'm implementing a REST-API in Java, using Jersey3 and a Tomcat10. In order to provide/restrict access to some endpoints for specific roles, I would like to use a DataSourceRealm.
The configuration in my context.xml looks like this:
<Resource type="javax.sql.DataSource"
name="jdbc/myDB"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#//localhost:1521/orcl"
username="xx"
password="xx"/>
<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
dataSourceName="jdbc/myDB" localDataSource="true"
userTable="USERS" userNameCol="USERNAME" userCredCol="PASSWORD"
userRoleTable="USER_ROLES" roleNameCol="ROLENAME"/>
The dataSource is also defined in my context.xml and can be accessed with JNDI.
In my web.xml I defined the following security constraint:
<security-constraint>
<web-resource-collection>
<web-resource-name>Some name</web-resource-name>
<url-pattern>/api/data</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Administrator</role-name>
</auth-constraint>
</security-constraint>
So every GET request with the pattern /api/data requires the role Administrator
Table USER_ROLES has one entry with USERNAME=admin and ROLENAME=Administrator.
Also, I've added these lines:
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>Administrator</role-name>
</security-role>
For doing the obvious.
A corresponding endpoint is defined like this:
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/data")
#RolesAllowed({"Administrator"})
public Response getData(...)
Added these lines to my log-config:
org.apache.catalina.realm.level = ALL
org.apache.catalina.realm.useParentHandlers = true
org.apache.catalina.authenticator.level = ALL
org.apache.catalina.authenticator.useParentHandlers = true
Calling http://localhost:8080/myapp/api/data in a GET with Authentication header Basic YWRtaW46YWRtaW4= --> admin:admin
Restricting access so far works and my DataSourceRealm seems to be taken into account. Although there are no logs from the when someone is authenticating.
What would I need to add, in order so see logs from the DataSourceRealm?
Any help/input would be much appreciated.
I want to create a simple JSP/Servlet login page that authenticate using websphere ldap repository.
All examples I've found looks very complex, with hundreds of lines of code just to authenticate.
Is this really so complex?
Does anyone have a simple example or article that explains how to authenticate a user/pass against a ldap repository already configured as websphere federated repository?
I really appreciate any help.
Thanks
This is quit simple in reality. You need following pieces:
1) Login page with form that points to j_security_check
See this page for details Customizing web application login
Very simplified example is like this:
<form method="POST" action="j_security_check">
<input type="text" name="j_username">
<input type="text" name="j_password" autocomplete="off">
<\form>
2) Security configured in web.xml
Something like this:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp</form-error-page>
</form-login-config>
</login-config>
plus security constraint:
<security-constraint>
<display-name>allResources</display-name>
<web-resource-collection>
<web-resource-name>allResources</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>users</role-name>
</auth-constraint>
</security-constraint>
3) Application security enabled on the application server and user registry configured.
That's it.
I have a web application written in java and I want to protect everything that is inside admin folder which is inside WebContet folder. The issue is that the server constantly asks for username and password. My web.xml is:
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Constraint</web-resource-name>
<url-pattern>/admin/index.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>administration</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>DIGEST</auth-method>
<realm-name>AdministrationArea</realm-name>
</login-config>
My users xml file is
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<role rolename="administration"/>
<user username="admin" password="admin" roles="administration,tomcat"/>
<user username="tomcat" password="tomcat" roles="admin-gui,manager-gui"/>
And my server xml file is :
<Context path="/admin" docBase="admin"><Realm className="org.apache.catalina.realm.MemoryRealm"resourceName="AdministrationArea"digest="MD5"/></Context>
I am new to this. Help please.
The problem is not your Tomcat configuration, but just the way HTTP authentication works. The server will ask your browser to verify username and password on every request, which is why most browser will save username and password for at least a short while.
If you want to make your webapp secure you should think about adding your own security to it, including sessions and cookies. How to do that depends on your specific configuration and the frameworks you're using, so I can't really help you more with that.
I have set the realm setting in server.xml host section to something like this:
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles"
roleNameCol="user_role" />
Also in web.xml:
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>critical</web-resource-name>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
And I have the databased set up. However when login.jsp is envoked, even I entered the right password I was redirected to error.jsp
I want to know if there is a way to find what's wrong during the process. Can I do it in Eclipse or any other hints that may solve the problem?
To get the debug information from the Realm authentication steps, follow this procedure.
When you define your Realm in the server.xml, add debug="9" to the definition (you can of course use a lower number for less detail).
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles"
roleNameCol="user_role" debug="9" />
You also need to add this to your logging.properties file:
org.apache.catalina.realm.level = ALL
org.apache.catalina.realm.useParentHandlers = true
org.apache.catalina.authenticator.level = ALL
org.apache.catalina.authenticator.useParentHandlers = true
You may also need to add this, to prevent bufferring of the logs. If you do, remember to remove it after you've finished debugging.
1catalina.org.apache.juli.FileHandler.bufferSize = -1
Now, the debug logs for the realms should end up in the catalina.out file.
For others finding this issue, I found the following worked for Tomcat 8.5.40:
java.util.logging.ConsoleHandler.level = ALL
org.apache.catalina.level = FINEST
org.apache.catalina.realm.JNDIRealm.level = FINEST
org.apache.catalina.realm.JNDIRealm.useParentHandlers = true
The key fact appears to be that your logging travels through several layers of definitions and will be trimmed by the first one that has a lower level so you need to make sure that each bit it passes through is FINEST or ALL.
Hopefully this will save someone some time ;)
Ian.
I am trying to put user access level in My Java Web Application.But even I enter the correct username and password which I have declare in the tomcat-user.xml file It is not working. It gong to loginerror page. Basic Authentication Method also Not Accepting Correct Username and password.
This tomcat-users.xml
<tomcat-users>
<!--
NOTE: By default, no user is included in the "manager-gui" role required
to operate the "/manager/html" web application. If you wish to use this app,
you must define such a user - the username and password are arbitrary.
-->
<!--
NOTE: The sample user and role entries below are wrapped in a comment
and thus are ignored when reading this file. Do not forget to remove
<!.. ..> that surrounds them.
-->
<!--
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>
-->
<role rolename=”Admin”/>
<role rolename=”Member”/>
<role rolename=”Doctor”/>
<role rolename=”Guest”/>
<user username=”sirojan” password=”sirojan” roles=”Admin” />
<user username=”ram” password=”ram123” roles=”Member” />
<user username=”vithu” password=”newbie” roles=”Guest” />
</tomcat-users>
This is a part of server.xml file
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.MemoryRealm" />
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<!-- <Realm className="org.apache.catalina.realm.MemoryRealm" /> -->
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/><!--
--> </Realm>
This is My a part of web.xml file
<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-role>
<role-name>Doctor</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login2.jsp</form-login-page>
<form-error-page>/loginerror.jsp</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminTasks</web-resource-name>
<url-pattern>/Department.jsp</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
<role-name>Member</role-name>
</auth-constraint>
</security-constraint>
<error-page>
<error-code>404</error-code>
<location>/notFoundError.jsp</location>
</error-page>
</web-app>
Did I anything wrong??. If you need further pl comment it. Can you please give the solutions for that??
first check whether the existing roles are working for you or not .
for that u need to uncomment the roles in tomcat-users.xml
if they are working ,and u r able to login in tomcat console, then problem is ur syntax ,
if they are not working then u need to go with the error page documentation and check what u r doing is correct or not because this is kind of easy and works every time for me .