Hey there im currently working on a application in tomcat and im trying to access a DataSource thats defined in the tomcat's server.xml. However im unable to access the resource and it will always return an empty DataSource. The servlet is able to access resources defined on the local level. My question is why is my application unable to access global resources?
The exception im getting when trying to access the database is: java.sql.SQLException: Cannot create JDBC driver of class '' for connect URL 'null'
server.xml
<GlobalNamingResources>
<Resource name="jdbc/AuthenticationDatabase" auth="Container" type="javax.sql.DataSource" username="tomcat" password="tomcat" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/tomcat" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" />
</GlobalNamingResources>
AdminPanel.java
#WebServlet(name = "adminpanel", value = "/restricted/user-management")
public class AdminPanel extends HttpServlet {
private List<User> users;
private final String PreparedUsersSelectQuery = "SELECT active, user_name FROM users";
private final String PreparedRoleSelectQuery = "SELECT role_name FROM user_roles WHERE user_name = ?";
Context initCtx = new InitialContext();
Context EnvCtz = (Context) initCtx.lookup("java:comp/env");
DataSource userDB = (DataSource) EnvCtz.lookup("jdbc/AuthenticationDatabase");
public AdminPanel() throws NamingException {
}
protected void ProcessRequest(HttpServletRequest request, HttpServletResponse response) {
users = new ArrayList<>();
try {
Connection conn = userDB.getConnection();
PreparedStatement stmt = conn.prepareStatement(PreparedUsersSelectQuery);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
User user = new User(rs.getString("user_name"), rs.getBoolean("active"));
PreparedStatement roleStmt = conn.prepareStatement(PreparedRoleSelectQuery);
roleStmt.setString(1, user.username);
ResultSet roleResults = roleStmt.executeQuery();
while (roleResults.next()) {
user.roles.add(roleResults.getString("role_name"));
}
users.add(user);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
request.setAttribute("data", users);
RequestDispatcher dispatcher = request.getRequestDispatcher("ListUsers.jsp");
try {
dispatcher.forward(request, response);
} catch (ServletException | IOException e) {
throw new RuntimeException(e);
}
}
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ProcessRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ProcessRequest(req, resp);
}
public void destroy() {
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<resource-ref>
<description>Access to the userdatabase for the purpose of modifying the user data</description>
<res-ref-name>jdbc/AuthenticationDatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Panel</web-resource-name>
<url-pattern>/restricted/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin-user</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>admin-user</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>User Management</realm-name>
</login-config>
</web-app>
Thanks for any and all assistance in this matter.
Related
I have a servlet deployed
Myservlet.java
#Configurable
public class MyServlet extends HttpServlet {
#Autowired
MyService service;
#Override
public void init(ServletConfig config) throws javax.servlet.ServletException{
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
//Do something here
}
Now the security for this is enabled in web.xml as :
<security-constraint>
<web-resource-collection>
<web-resource-name>myServlet</web-resource-name>
<url-pattern>/myUrl/*</url-pattern>
<http-method>HEAD</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
But where this spring application deployed already has a spring security enabled via #EnableWebSecurity
The controllers deployed in the spring application are all correctly getting authenticated as expected. But the servlet is not authenticating with spring security. I believe what's mentioned in the is stopping it from authenticating.
How do i make the servlet work with Spring security ?
Edit 1:
Spring security configuration: (Note that this is not syntactically correct) but user/role and datasource are all correct in my code. It's working fine for other REST apis deployed in spring application
#Configuration
#EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
String user_query = "select user from userTable where id=9999";
String role_query = "select role from roleTable where id=6666";
logger.info("Using the following query for role : " + role_query);
auth.
jdbcAuthentication()
.dataSource(dataSource) //Datasource is injected to this class
.usersByUsernameQuery(user_query)
.passwordEncoder(passwordEncoder())
.authoritiesByUsernameQuery(role_query);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().hasRole("myrole")
.and()
.httpBasic();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(runAsAuthenticationProvider());
}
#Autowired
protected RunAsManager runAsManager() {
RunAsManagerImpl runAsManager = new RunAsManagerImpl();
runAsManager.setKey("MyRunAsKey");
return runAsManager;
}
i am going to call firebase Http request from a cron job i setup on google app engine.the cron job is deployed successfully but it did not trigger the firebase url as i think i am missing some setting in the web.xml file or in other files.
In the log viewer i see this type of info "No handlers matched this URL"
Any one have any idea.Any would be appreciated.
Following is my cron.xml setting
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/cron</url>
<target>beta</target>
<description>Keymitt cron job</description>
<schedule>every 1 minutes</schedule>
</cron>
</cronentries>
this is my web.xml setting
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>HelloAppEngine</servlet-name>
<servlet-class>com.company.HelloAppEngine</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloAppEngine</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>KeymittCron</servlet-name>
<servlet-class>com.company.KeymittCron</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>KeymittCron</servlet-name>
<url-pattern>/cron</url-pattern>
</servlet-mapping>
</web-app>
and this is my associated WebServlet
#WebServlet(name = "KeymittCron",value = "/cron")
public class KeymittCron extends HttpServlet {
private static final Logger _logger = Logger.getLogger(KeymittCron.class.getName());
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
URL url=new URL("httplink");
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.connect();
int requestCode=connection.getResponseCode();
if(requestCode==200){
_logger.info("firebase link triggered successfully");
_logger.info("Executed cron job");
}
else{
_logger.info("Error while triggering firebase link");
}
connection.disconnect();
resp.setStatus(200);
resp.getWriter().println("Done");
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//
doGet(req,resp);
}
}
And this is my Logger info
My answer here may be relevant - Google Cloud App Engine cron job - not calling the service
Basically, you may need this in your appengine-web.xml:
<service>beta</service>
The <target> you specify in your cron.xml must match the <service> you define in your appengine-web.xml
I need to remember the original URL of the Http Request, then redirect this request to a web form for a user authentication. In case of a successful authentication, the user must be redirected to the original URL just remembered above.
I am using JBoss 7.1.1 Final, a standard web.xml, and the JBoss Login Module org.jboss.security.auth.spi.DatabaseServerLoginModule:
I had referred the following links which didn't answer my question completely:
Precedence of security-constraint over filters in
Servlets
Jaspic ServerAuthModule delegating to JAAS Krb5LoginModule
Implementing container authentication in Java EE with JASPIC
Oracle GlassFish Server 3.0.1 Application Development Guide
However, after impltementing my solution, my custom ServerAuthModule is not called at all. What is even worse, I did not get any HttpResponse from the server. Something got broken, please help!
My web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>All resources in /pages/*</web-resource-name>
<description>All resources in /pages/*</description>
<url-pattern>/pages/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>general</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>Restrict direct access to the /resources folder.</display-name>
<web-resource-collection>
<web-resource-name>The /resources folder.</web-resource-name>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsf</form-login-page>
<form-error-page>/loginFailed.jsf</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>general</role-name>
</security-role>
My jboss-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>jBossJaasMysqlRealm</security-domain>
<valve>
<class-name>org.jboss.as.web.security.jaspi.WebJASPIAuthenticator</class-name>
</valve>
</jboss-web>
My standalone.xml:
<security-domain name="jBossJaasMysqlRealm" cache-type="default">
<authentication-jaspi>
<login-module-stack name="lm-stack">
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="dsJndiName" value="java:/MySqlDS_IamOK"/>
<module-option name="principalsQuery" value="select password from user where username=?"/>
<module-option name="rolesQuery" value="select role, 'Roles' from user_role where username=?"/>
</login-module>
</login-module-stack>
<auth-module code="at.alex.ok.web.utils.RequestMarkerServerAuthModule" login-module-stack-ref="lm-stack"/>
</authentication-jaspi>
</security-domain>
My custom WebServerAuthModule:
import org.jboss.as.web.security.jaspi.modules.WebServerAuthModule;
public class RequestMarkerServerAuthModule extends WebServerAuthModule {
public static final String ORIGINAL_URL = "originalURL";
protected static final Class[] supportedMessageTypes = new Class[] {
HttpServletRequest.class, HttpServletResponse.class };
public void initialize(MessagePolicy reqPolicy, MessagePolicy resPolicy,
CallbackHandler cBH, Map opts) throws AuthException {
System.out.println( this.getClass().getName() + ".initialize() called");
}
public Class[] getSupportedMessageTypes() {
return supportedMessageTypes;
}
public AuthStatus validateRequest(MessageInfo msgInfo, Subject client,
Subject server) throws AuthException {
try {
System.out.println( this.getClass().getName() + ".validateRequest() called");
processAuthorizationToken(msgInfo, client);
return AuthStatus.SUCCESS;
} catch (Exception e) {
AuthException ae = new AuthException();
ae.initCause(e);
throw ae;
}
}
private void processAuthorizationToken(MessageInfo msgInfo, Subject s)
throws AuthException {
HttpServletRequest request = (HttpServletRequest) msgInfo
.getRequestMessage();
String originalURL = request.getRequestURL().toString();
request.getSession().setAttribute(ORIGINAL_URL, originalURL);
}
public AuthStatus secureResponse(MessageInfo msgInfo, Subject service)
throws AuthException {
System.out.println( this.getClass().getName() + ".secureResponse() called");
return AuthStatus.SEND_SUCCESS;
}
public void cleanSubject(MessageInfo msgInfo, Subject subject)
throws AuthException {
System.out.println( this.getClass().getName() + ".cleanSubject() called");
}
}
This question is put incorectly, because:
For a redirect to the originally requested URL after a successfull login, there is no need to implement a custom ServerAuthModule for JBoss.
The interface javax.servlet.RequestDispatcher has the constant FORWARD_REQUEST_URI, which denotes the name of the Http-Request attribute under which the original request URI is made available to the processor of the forwarded request.
Using JSF 2.2 and a View-Scoped backing bean LoginBean, my solution is simply to obtain the originally requested URL in a #PostConstruct method of the backing bean, and store it in a session attribute, as follows:
#ManagedBean(name="loginBean")
#ViewScoped
public class LoginBean {
private String originalURL;
#PostConstruct
private void init() {
ExternalContext extCtx = FacesContext.getCurrentInstance().getExternalContext();
String origURL = (String) extCtx.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
HttpServletRequest request = (HttpServletRequest) extCtx.getRequest();
HttpSession session = (HttpSession)extCtx.getSession(false);
if (session == null){
session = (HttpSession)extCtx.getSession(true);
}
if (origURL!=null && session.getAttribute(ORIGINAL_URL) == null){
String applicationName = request.getContextPath();
origURL = origURL.substring(applicationName.length(), origURL.length());
session.setAttribute(ORIGINAL_URL, origURL);
}
}
Then, in the login() method of the same backing bean, redirect the user to the originally requested URL in case of a successfull log-in like this:
public String login() {
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
try {
request.login(this.getLogin(), this.getPassword());
} catch (ServletException e) {
// handle bad username / password here
}
return this.originalURL + "?faces-redirect=true";
}
I've just gotten into servlets and I cannot display the information on tomcat.
This is my class with the doGet method
public class WhoisOlder extends HttpServlet {
private static final long serialVersionUID = 1L;
public WhoisOlder() {
super();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final String OJDBC_Driver = "oracle.jdbc.driver.OracleDriver";
final String DB_URL = "";
final String USER = "";
final String PASS = "";
try {
Class.forName(OJDBC_Driver);
Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT GEBDAT FROM KLASSE");
while (rs.next()) {
System.out.println(rs.getString("GEBDAT"));
}
rs.close();
stmt.close();
con.close();
} catch (SQLException se) {
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
I get the "Error instantiating servlet class" error, when I run the code on my browser. I have checked if the servlet name, servlet URL is correct, which it is. Is the code false in my class, which preventing to instantiate the class?
EDIT: Below is the exception and the root log.
java.lang.ClassNotFoundException: WhoisOlder
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2466)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2455)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
EDIT 2: My web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<description>OJDBCAnbindung</description>
<display-name>OJDBCAnbindung</display-name>
<servlet>
<servlet-name>WhoisOlder</servlet-name>
<servlet-class>WhoisOlder</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WhoisOlder</servlet-name>
<url-pattern>/WhoisOlder</url-pattern>
</servlet-mapping>
</web-app>
Put your servlet in a package, compile the .class file to the WEB-INF/classes folder. Change your web.xml to add the package name to your servlet's class file.
I am trying a servlet that puts the data into the database:derbi (that comes packed with netbeans). When a user clicks to submit data,the request follows to the FormHandler servlet (given below) If any of the text-field was empty the request follows to another servlet ErrorServlet and if every thing was fine the request follows to the Registered servlet. But before the request follows to the Registered Servlet there is a small code that is written to insert the data into the database (After this code the the user views the success page,that he has been registered).
Now the problem : The user fills all the text fields in the form and clicks submit. When he clicks submit,he sees the success page displaying Registered Successfully . But when i query the databse, i see that the data wasn't submitted to the databse. The rows and columns are empty ! I don't understand the reason for this .
Code for FormHandler.java :
package FormHandler;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.LinkedList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class FormHandler extends HttpServlet {
#Override
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
}
#Override
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
String name = request.getParameter("Name");
String email = request.getParameter("Email");
String password = request.getParameter("Password");
LinkedList list = new LinkedList();
if(name.compareTo("") == 0 || email.compareTo("") == 0 || email.compareTo("") == 0) {
list.add("One or more field's' left blank");
request.setAttribute("ErrorList", list);
RequestDispatcher rd = request.getRequestDispatcher("ErrorServlet.view");
rd.forward(request, response);
} else {
try {
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/MyDatasource");
Connection connection = ds.getConnection();
String sqlStatement = "INSERT INTO INFORMATION VALUES('" + name + "'," + "'" + email + "'," + "'" + password + "')";
PreparedStatement statement = connection.prepareStatement(sqlStatement);
ResultSet result = statement.executeQuery();
}catch(Exception exc) {
System.out.println(exc);
}
request.setAttribute("Data", list);
RequestDispatcher rd = request.getRequestDispatcher("Registered.view");
rd.forward(request, response);
}
}
}
XML file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>FormHandler</servlet-name>
<servlet-class>FormHandler.FormHandler</servlet-class>
</servlet>
<servlet>
<servlet-name>Registered</servlet-name>
<servlet-class>FormHandler.Registered</servlet-class>
</servlet>
<servlet>
<servlet-name>ErrorServlet</servlet-name>
<servlet-class>FormHandler.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FormHandler</servlet-name>
<url-pattern>/FormHandler.do</url-pattern>
</servlet-mapping>
<resource-ref>
<res-ref-name>jdbc/MyDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<servlet-mapping>
<servlet-name>Registered</servlet-name>
<url-pattern>/Registered.view</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/ErrorServlet.view</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
Html File :Code for html file
Note : I have already made a connection to database
I think you are getting somewhere a :
java.sql.SQLException: No ResultSet was produced
because executing your UPDATE query with executeQuery() actually returns no resultset
Use:
statement.executeUpdate();
try the following:
PreparedStatement ps2=null;
ps2 = connection.prepareStatement("INSERT INTO INFORMATION( colname1, colname2,colname3) VALUES(? ,? ,?)");
ps2.setString(1, name);
ps2.setString(2, email);
ps2.setString(3, password);
try {
rs=ps2.executeUpdate();
} catch (SQLException ex) {
// catch if any exception
}