Results 1 to 7 of 7

Thread: How to store user in the HttpSession on login?

  1. #1

    Default How to store user in the HttpSession on login?

    Hi,

    I'm implementing my own UserDetailsService to validate login process against the database users. I'm using spring 3.0.7., with Spring security 3.0.7. I have a entity SystemUser, from which I create UserDetail entity needed in Spring Security.

    PHP Code:
    package com.objectverse.system.login.service;

    import java.util.ArrayList;
    import java.util.Collection;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DataAccessException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.GrantedAuthorityImpl;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import com.objectverse.system.login.repository.UserDetailsDao;
    import com.objectverse.system.users.user.model.SystemUser;

    @
    Service("userDetailsService")
    public class 
    UserDetailsServiceImpl implements UserDetailsService {
        
        private static 
    Log logger LogFactory.getLog(UserDetailsServiceImpl.class);
        
        @
    Autowired
        
    private UserDetailsDao userDetailsDao;
        
        @
    Override
        
    @Transactional
        
    public UserDetails loadUserByUsername(String username)
                
    throws UsernameNotFoundExceptionDataAccessException {
            if (
    logger.isDebugEnabled()) {
                
    logger.debug("UserDetailsServiceImpl::getSystemUSer");
            }
            
            
    SystemUser systemUser this.userDetailsDao.findByUsername(username);
            if (
    systemUser != null) {
                
    //RequestContextHolder.currentRequestAttributes().setAttribute("profile", systemUser, RequestAttributes.SCOPE_SESSION);

                            // In this point I'd like to store the systemUser in httpSession or any object available throughout the application (session scope).


                
    boolean accountNonExpired systemUser.getActive();
                
    boolean credentialsNonExpired systemUser.getActive();
                
    boolean accountNonLocked systemUser.getActive();
                
                
    Collection<GrantedAuthorityauthorities = new ArrayList<GrantedAuthority>();
                
    authorities.add(new GrantedAuthorityImpl("ROLE_USER"));
                
                
    User user = new User(
                            
    systemUser.getUsername(), systemUser.getPassword(), systemUser.getActive(), 
                            
    accountNonExpiredcredentialsNonExpiredaccountNonLockedauthorities);
                return 
    user;
                
            }
            throw new 
    RuntimeException("Access denied.");
        }
            


    My config
    PHP Code:
    <security:http auto-config="true" use-expressions="true">
            <
    security:intercept-url pattern="/app/login*" access="permitAll"/>
            <
    security:intercept-url pattern="/app/signin" access="permitAll"/>
            <
    security:intercept-url pattern="/app/**" access="isAuthenticated()"/>
               <
    security:intercept-url pattern="/**" access="permitAll" />
            <
    security:form-login login-page="/app/login.jsp" authentication-failure-url="/app/login.jsp?error=failed" default-target-url="/app/desktop"/>
            <
    security:logout logout-url="/app/logoff" logout-success-url="/app/login"/>
               <
    security:session-management>
                <
    security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
            </
    security:session-management>
        </
    security:http>

        <
    bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
              <
    property name="userDetailsService" ref="userDetailsService"/>
        </
    bean>

        <
    bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
              <
    property name="providers">
                <list>
                    <
    ref local="daoAuthenticationProvider" />
                </list>
              </
    property>
        </
    bean>

        <
    security:authentication-manager>
              <
    security:authentication-provider user-service-ref="userDetailsService">
                <
    security:password-encoder hash="plaintext"/>
              </
    security:authentication-provider>
        </
    security:authentication-manager
    I have 3 questions regarding my configuration:

    1. As commented in the code I'd like to store my systemUser in httpSession or any object available throughout the application (session scope). How can I do that as the method is in the service layer and the bean is initialized when the application starts.

    2. How can I handle Exceptions? If an exception occurs I get a page with stacktrace?

    3. I'd like to add some logic where the system checks if there are any users in the database - the user is redirected to desktop and if there is no user in the database, the user is redirected to install.

    Any help appreciated.

    Bojan

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Trust me you don't... I suggest a read on how spring security works and which components do what in Spring Security at least for 1 and 2. for 3 use a separate filter.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Apr 2011
    Posts
    17

    Default

    Hi

    I have a question. This is not actually related to your issue. I'm trying to get spring security working with my mvc app.
    I have a preatty similar setup as you do. There are some differences in the userDetailsService, I use (or should i say want to use) a CRUDRepository to access the user information. The class Customer extends UserDetails.

    Code:
    @Service("userDetailsService")
    public class UserDetailsServiceImpl implements UserDetailsService {
    
    	private Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    
    	@Autowired
    	CustomerRepository customerRep;
    
    	@Override
    	@Transactional(readOnly = true)
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException {
    		log.debug("Getting user for username " + username);
    		Customer customer = customerRep.findByUsername(username);
    		if(customer == null){
    			throw new UsernameNotFoundException("Username " + username + " not found.");
    
    		}
    		return customer;
    	}
    }
    My security.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!-- - Sample namespace-based configuration - -->
    
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
    	<global-method-security pre-post-annotations="enabled">
    		<!-- AspectJ pointcut expression that locates our "post" method and applies 
    			security that way <protect-pointcut expression="execution(* bigbank.*Service.post*(..))" 
    			access="ROLE_TELLER"/> -->
    	</global-method-security>
    
    	<http auto-config='true' use-expressions="true">
    		<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    		<intercept-url pattern="/**" access="ROLE_USER" />
    		<form-login login-page="/login.jsp" />
    	</http>
    
    	<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
              <beans:property name="userDetailsService" ref="userDetailsService"/> 
        </beans:bean> 
    
        <beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager"> 
              <beans:property name="providers"> 
                <beans:list> 
                    <beans:ref local="daoAuthenticationProvider" /> 
                </beans:list> 
              </beans:property> 
        </beans:bean>
    	
    	<authentication-manager>
    		<authentication-provider user-service-ref="userDetailsService">
    		</authentication-provider>
    	</authentication-manager>
    </beans:beans>
    For some reason that I haven't yet figured out, I can't get this setup working. I get this error:

    Code:
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDetailsService' is defined
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:277)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
    	... 94 more
    I'm probably missing some configuration, some detail. Since you have such a similar setup I was hoping you ran into this issue already.

    I hope you can help me, otherwise I'll post this in a new thread.

  4. #4
    Join Date
    Dec 2010
    Location
    Singapore
    Posts
    302

    Default

    Judging by your code, you should have something similar to below in your configurations,

    Code:
    <context:component-scan base-package="bla bla"/>
    Amila Domingo

  5. #5

    Default

    Quote Originally Posted by Marten Deinum View Post
    Trust me you don't... I suggest a read on how spring security works and which components do what in Spring Security at least for 1 and 2. for 3 use a separate filter.
    So, if I understood correctly, I should just use UserDetail from the Spring Security and load SystemUser on demand, when I need it? The case is that the SystemUser is quite complex - it is connected with profile configuration, resource configuration etc, which take some time to load...

  6. #6

    Default

    My mistake - I've just seen UserDetails is an interface. So I added Interface definitions to my SystemUser and replaced the code where I retrieve a SystemUser from session. Everything works now.

    I still have problems with the failed login. Instead of displaying custom form, with an error message I get stacktrace.
    I'm going back to tutorials, hope I'll found a problem.

    Best regards,
    Bojan

  7. #7
    Join Date
    Apr 2011
    Posts
    17

    Default

    Quote Originally Posted by amiladomingo View Post
    Judging by your code, you should have something similar to below in your configurations,

    Code:
    <context:component-scan base-package="bla bla"/>
    I have that, that's what bothers me. I believe that it's a config order thing, but i'm going to create a thread about it. Anyway, thank you for your help

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •