Monday, October 22, 2012

How to add Oracle JDBC driver in your Maven local repository

I found the below blog very helpfull for this information
 http://www.mkyong.com/maven/how-to-add-oracle-jdbc-driver-in-your-maven-local-repository/

Which in short guides to do following steps in order to add your JDBC driver to your Maven local repository

Run below mvn command

mvn install:install-file -Dfile=D:\app\mkyong\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar  -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar

of course you will have to replace the path to OJDBC jar file with your machine's path. Maven will show you a build success message. After that you will have to add following dependency to your project's pom.xml


  <!-- ORACLE database driver -->
  <dependency>
   <groupId>com.oracle</groupId>
   <artifactId>ojdbc6</artifactId>
   <version>11.2.0</version>
  </dependency>
and there you go. Oracle driver is now installed in maven repository.

  

Friday, October 19, 2012

Enabling spring security in your spring application


Enabling spring security in your spring application

In your roo application you will have to run following command which will generate all the security related pages and needed configuration for you.

Roo> Security Setup

The above command will create everything needed for spring security , now go to your “applicationContext-security.xml” file under your project’s  resources/META-INF/spring  folder.
If you want Spring to show login screen whenever your user want’s to access any URL then include following interceptors  in your applicationContext-security.xml  file under http tage

    <http auto-config="true" use-expressions="true">
        <!--
   
            <form-login />
         -->
       
<form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
       
       

        <logout logout-url="/resources/j_spring_security_logout" />
        <!-- Configure these elements to secure URIs in your application -->
        <intercept-url pattern="/login**" access="permitAll" />
        <intercept-url pattern="/**" access="isAuthenticated()" />
    </http>
 
Note the  bold lines in above code , the first line will tell spring to allow access to /login URL only , while the second line will restrict all the other URLS in your application and will allow access only if the user is authenticated and has required roles.
Note that if you don’t want to have your own login page and want spring to handle security (login page based) then comment the below line
<form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
       
And uncomment below line
        <!--
   
            <form-login />
         -->

Try to run your spring application now and spring will still show you a login page and notice that you don’t need to create a login.jsp page in this case.


Customizing Spring Security
We can even customize the spring security to use our own class where we can put the code to authenticate the user against our database , please follow the steps mentioned below

Writing custom AuthenticationProvider
We will write a custom Authentication provider by extending a classcalled AbstractUserDetailsAuthenticationProvider, which works with username/password like authentication. The classes that extend AbstractUserDetailsAuthenticationProvider have to provide implementation for its two abstract methods:
·         additionalAuthenticationChecks and
·          retrieveUser.
The provider calls the retrieveUser method to authenticate user , this is where you can authenticate the user in your application against your own database , below is the class

package mypackage;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

public class DrillingBestPracticesAuthenticationProvider extends
              AbstractUserDetailsAuthenticationProvider {

       @Override
       protected void additionalAuthenticationChecks(UserDetails arg0,
                     UsernamePasswordAuthenticationToken arg1)
                     throws AuthenticationException {
              // TODO Auto-generated method stub

       }

       @Override
       protected UserDetails retrieveUser(String username,
                     UsernamePasswordAuthenticationToken authentication)
                     throws AuthenticationException {
              String password = (String) authentication.getCredentials();
              if (!StringUtils.hasText(password))
              {
                     throw new BadCredentialsException("Please enter password");
             
              }
              List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
              try
              {
                    
                     //TODO here I should be trying to get the database connection using user name and password if connection successfully made then it means user is authenticated to use our system
                    
                    
              }
              catch (EmptyResultDataAccessException e)
              {
                     throw new BadCredentialsException("Invalid username or password");
                    
              } catch (EntityNotFoundException e) {
                     throw new BadCredentialsException("Invalid user");
                    
              } catch (NonUniqueResultException e) {
                     throw new BadCredentialsException("Non-unique user, contact administrator");
                    
              }
              return new User(username, password,
                           true, // enabled
                           true, // account not expired
                           true, // credentials not expired
                           true, // account not locked
                           authorities);       
       }

}

And you will have to add AuthenticationManager in your applicationContext-security.xml file as below


<beans:bean name="drillingBestPracticesAuthenticationProvider" class="mypackage.DrillingBestPracticesAuthenticationProvider">
    
    </beans:bean>
    <authentication-manager alias="authenticationManager">
    <authentication-provider ref="drillingBestPracticesAuthenticationProvider"></authentication-provider>
    </authentication-manager>    


Now once the user has been authenticated and User object being returned by the retrieveUser method , Spring will allow you to get user detail from anywhere in your application using any of the three approaches mentioned in the blogpost at following link
I am copy pasting the three methods mentioned in above blog
 three ways to get current logged in username in Spring Security

First Method
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      String name = auth.getName(); //get logged in username
Second Method
     User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
      String name = user.getUsername(); //get logged in username
Third Method
  @RequestMapping(value="/login", method = RequestMethod.GET)
  public String printWelcome(ModelMap model, Principal principal ) {
 
      String name = principal.getName(); //get logged in username
      model.addAttribute("username", name);
      return "hello";
 
  }

Saturday, October 13, 2012

Weblogic BEA-149265 , Caused By: java.lang.ClassNotFoundException: HttpServlet


Problem Description
I am using weblogic 10.3.3 server and was trying to deploy a web based application (build in eclipse).

 I have configured weblogic 10.3.3 server in eclipse and the application had no errors. It was running from inside eclipse like a charm.
After finishing the development and to test the application outside eclipse environment, I started standalone server instance (weblogic 10.3.3 outside eclipse , from command prompt) and was trying to deploy the same application and saw this strange error

<Error> <Deployer> <BEA-149265> <Failure occurredin the execution of deployment request with ID '1350125256034' for task '6'. Error is: 'weblogic.management.DeploymentException: 'weblogic.management.DeploymentException:        at weblogic.application.internal.BaseDeployment.throwAppException(BaseDe
ployment.java:157)

Caused By: java.lang.ClassNotFoundException: HttpServlet
        at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(Generic
ClassLoader.java:280)
        at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClass
Loader.java:253)
        at weblogic.utils.classloaders.ChangeAwareClassLoader.findClass(ChangeAw
areClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        Truncated. see log file for complete stacktrace
> 

I was surprised to see it because same machine same server instance , if I run it from eclipse it works fine , outside eclipse it doesn’t work.
As you can see from the error message it was having problem loading the HTTPServlet  while deploying the application.
But the thing which wasted a lot of time was why the hell it is working on eclipse , as I was using the same weblogic server.
Ideally the servlet jar file shouldn’t be in your webapp/lib directory and it wasn’t , server will have it’s own copy of the jar file in it’s class loader.
Solution
It took some time to find the solution but it’s easy. I used eclipse to export a war file of my web project, and then started weblogic and deployed the war file instead of web app folder and it’s working now.
Similar problem encountered at test server
I saw the same problem on test even with the war file , after trying everything we can do to get rid of this problem with no success we decided to restart the Test instance.
The application was deployed successfully after Server restart.

Infect this solution should be followed as a practice
 When you export war file eclipse takes care of all the dependent jars and puts them in your war file , so if there is any possibility that you are using an external  library in your application eclipse will take care of including it in the final war when you export the project as a war file.
It is therefore highly recommended to export your eclipse project as WAR file and then send it for deployment.