Announcement Announcement Module
Collapse
No announcement yet.
Provide authentication in my Spring web application for third party web applications Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Provide authentication in my Spring web application for third party web applications

    Hi,

    First, sorry for my English!!

    My company has developed a Spring web application using athentication by jcifs in a OpenLDAP directory. It's works along time without problems.

    Security config in web-application-config.xml is:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
      xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/security
               http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
    
      <!-- Configure Spring Security -->
      <security:http auto-config="true" access-denied-page="/spring/error403"  >
        <security:form-login login-page="/spring/login" login-processing-url="/spring/loginProcess" default-target-url="/spring/intro" authentication-failure-url="/spring/login?login_error=1" />
        <security:logout logout-url="/spring/logout" logout-success-url="/spring/logoutSuccess" />
        <security:anonymous />
        <security:remember-me />
      </security:http>
    
      <bean id="MyAppUserDetailsServiceImpl" class="es.mycompany.myapp.security.MyAppUserDetailsServiceImpl">
      </bean>
    
      <bean id="MyAppLdapAuthenticationProvider" class="es.mycompany.myapp.security.MyAppLdapAuthenticationProvider">
        <security:custom-authentication-provider/>
        <property name="ldapTemplate" ref="ldapTemplate" />
        <property name="userDetailsService" ref="MyAppUserDetailsServiceImpl" />
        <property name="hostLdap" value="${ad.ldap.host}" />
      </bean>
      
    </beans>
    MyAppAuthenticationProvider.java is:

    Code:
    public class MyAppLdapAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    
      @Autowired
      private UsuarioLdapService service;
    
      @Autowired
      private transient HashMap<String, Object> generalProperties;
    
      private LdapTemplate ldapTemplate;
    
      private String hostLdap;
    
      private UserDetailsService userDetailsService;
    
      protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
    
      public MyAppLdapAuthenticationProvider() {
        super();
      }
    
      public UserDetailsService getUserDetailsService() {
        return userDetailsService;
      }
    
      public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
      }
    
      public LdapTemplate getLdapTemplate() {
        return ldapTemplate;
      }
    
      public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
      }
    
      public String getHostLdap() {
        return hostLdap;
      }
    
      public void setHostLdap(String hostLdap) {
        this.hostLdap = hostLdap;
      }
    
      @Override
      @Transactional
      public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, messages.getMessage(
            "AbstractUserDetailsAuthenticationProvider.onlySupports",
            "Only UsernamePasswordAuthenticationToken is supported"));
    
        UsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;
    
        String username = userToken.getName();
    
        if (!StringUtils.hasLength(username)) { throw new BadCredentialsException(messages.getMessage(
            "LdapAuthenticationProvider.emptyUsername", "Empty Username")); }
    
        String password = (String) authentication.getCredentials();
    
        try {
          UserDetails user = userDetailsService.loadUserByUsername(username);
          
          if ((user instanceof UsuarioLdap) && (((UsuarioLdap) user).getUser() == null)) {
        	  throw new BadCredentialsException(messages.getMessage("LdapAuthenticationProvider.notFound", "User not found!")); }
          
          boolean authenticated = false;
    
          // JCIFS TEST
          try {
    
            jcifs.UniAddress uniaddress = UniAddress.getByName(getHostLdap());
            String domain = ((UsuarioLdap)user).getCentro().getDominio();
    
            NtlmPasswordAuthentication ntlmpasswordauthentication = new NtlmPasswordAuthentication(domain, username, password);
            SmbSession.logon(uniaddress, ntlmpasswordauthentication);
    
            // If not throw exception is authenticated!!!
            authenticated = true;
    
          } catch (SmbException e) {
            logger.log(Level.INFO, "Authentication failed!");
            e.printStackTrace();
    
            throw new BadCredentialsException(messages.getMessage("LdapAuthenticationProvider.notFound", "Authentication failed!"));
          } catch (UnknownHostException e) {
            logger.log(Level.SEVERE, "LDAP host not found!");
            e.printStackTrace();
    
            throw new BadCredentialsException(messages.getMessage("LdapAuthenticationProvider.notFound", "LDAP host not found!"));
          }
    
         if (authenticated)
             return new UsernamePasswordAuthenticationToken(user, userToken.getCredentials(), user.getAuthorities());
    
        } catch (NamingException ldapAccessFailure) {
          throw new AuthenticationServiceException(ldapAccessFailure.getMessage(), ldapAccessFailure);
        }
      }
    
      @Override
      public boolean supports(Class authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
      }
    
      @Override
      protected void additionalAuthenticationChecks(UserDetails userDetails,
          UsernamePasswordAuthenticationToken authentication) throws org.springframework.security.AuthenticationException {
    
      }
    MyAppUserDetailsServiceImpl.java is:

    Code:
    public class MyAppUserDetailsServiceImpl implements UserDetailsService {
    
      @Autowired
      private UsuarioLdapService service;
    
      @Transactional(readOnly = true)
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
    
        UsuarioLdap user = new UsuarioLdap();
        user.setUsername(username);
    
        try {
          attachUserInformation(user);
        } catch (DataAccessException repositoryProblem) {
          throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
        }
    
        if (user == null) throw new AuthenticationServiceException("User cannot be null");
    
        return user;
      }
    
      private void attachUserInformation(UsuarioLdap user) {
        try {
          UsuarioMyApp u = service.findOneWhere(UsuarioMyApp.class, "username", user.getUsername());
    
          if (u != null)
            user.setUser(u);
    
       } catch (RuntimeException e) {
          logger.log(Level.SEVERE, "Error extracting user data from database: " + e.getLocalizedMessage());
          e.printStackTrace();
        }
      }
    
      private void addRole(UsuarioLdap user, Role role) {
        if (!user.getRolesList().contains(role))
          user.getRolesList().add(role);
      }
    Well, our client has other provider who develop othe web application and wants that another web application has a login/password form that uthenticates in my company's application but without redirecting to my company's application.

    Additionaly, if after user authenticates in thid party application, he navigates to my company's app, this does not request credentials.

    I think I have to implement a remote authentication service but after reading a lot of documentation, I don't know I have to do.

    Can anyone help me?

    Thank you in advance.
    Last edited by Quoyle; Oct 18th, 2012, 03:26 AM.
Working...
X